a07ac13b61a17e302ad7bb9c9699b37b287e3b82
[WebKit-https.git] / Source / WebCore / css / CSSComputedStyleDeclaration.cpp
1 /*
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.
8  *
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.
13  *
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.
18  *
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
22  * 02110-1301  USA
23  */
24
25 #include "config.h"
26 #include "CSSComputedStyleDeclaration.h"
27
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 "CSSCustomPropertyValue.h"
36 #include "CSSFontFeatureValue.h"
37 #include "CSSFontValue.h"
38 #include "CSSFunctionValue.h"
39 #include "CSSLineBoxContainValue.h"
40 #include "CSSParser.h"
41 #include "CSSPrimitiveValue.h"
42 #include "CSSPrimitiveValueMappings.h"
43 #include "CSSPropertyNames.h"
44 #include "CSSReflectValue.h"
45 #include "CSSSelector.h"
46 #include "CSSShadowValue.h"
47 #include "CSSTimingFunctionValue.h"
48 #include "CSSValueList.h"
49 #include "CSSValuePool.h"
50 #include "ContentData.h"
51 #include "CounterContent.h"
52 #include "CursorList.h"
53 #include "Document.h"
54 #include "ExceptionCode.h"
55 #include "FontFeatureSettings.h"
56 #include "HTMLFrameOwnerElement.h"
57 #include "Pair.h"
58 #include "PseudoElement.h"
59 #include "Rect.h"
60 #include "RenderBlock.h"
61 #include "RenderBox.h"
62 #include "RenderStyle.h"
63 #include "SVGElement.h"
64 #include "StyleInheritedData.h"
65 #include "StyleProperties.h"
66 #include "StylePropertyShorthand.h"
67 #include "StyleResolver.h"
68 #include "WebKitCSSFilterValue.h"
69 #include "WebKitCSSTransformValue.h"
70 #include "WebKitFontFamilyNames.h"
71 #include "WillChangeData.h"
72 #include <wtf/NeverDestroyed.h>
73 #include <wtf/text/StringBuilder.h>
74
75 #if ENABLE(CSS_GRID_LAYOUT)
76 #include "CSSGridLineNamesValue.h"
77 #include "CSSGridTemplateAreasValue.h"
78 #include "RenderGrid.h"
79 #endif
80
81 #if ENABLE(CSS_SHAPES)
82 #include "ShapeValue.h"
83 #endif
84
85 #if ENABLE(DASHBOARD_SUPPORT)
86 #include "DashboardRegion.h"
87 #endif
88
89 #if ENABLE(CSS_SCROLL_SNAP)
90 #include "LengthRepeat.h"
91 #include "StyleScrollSnapPoints.h"
92 #endif
93
94 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
95 #include "AnimationTrigger.h"
96 #endif
97
98 namespace WebCore {
99
100 // List of all properties we know how to compute, omitting shorthands.
101 static const CSSPropertyID computedProperties[] = {
102     CSSPropertyAlt,
103     CSSPropertyAnimationDelay,
104     CSSPropertyAnimationDirection,
105     CSSPropertyAnimationDuration,
106     CSSPropertyAnimationFillMode,
107     CSSPropertyAnimationIterationCount,
108     CSSPropertyAnimationName,
109     CSSPropertyAnimationPlayState,
110     CSSPropertyAnimationTimingFunction,
111     CSSPropertyBackgroundAttachment,
112     CSSPropertyBackgroundBlendMode,
113     CSSPropertyBackgroundClip,
114     CSSPropertyBackgroundColor,
115     CSSPropertyBackgroundImage,
116     CSSPropertyBackgroundOrigin,
117     CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard
118     CSSPropertyBackgroundRepeat,
119     CSSPropertyBackgroundSize,
120     CSSPropertyBorderBottomColor,
121     CSSPropertyBorderBottomLeftRadius,
122     CSSPropertyBorderBottomRightRadius,
123     CSSPropertyBorderBottomStyle,
124     CSSPropertyBorderBottomWidth,
125     CSSPropertyBorderCollapse,
126     CSSPropertyBorderImageOutset,
127     CSSPropertyBorderImageRepeat,
128     CSSPropertyBorderImageSlice,
129     CSSPropertyBorderImageSource,
130     CSSPropertyBorderImageWidth,
131     CSSPropertyBorderLeftColor,
132     CSSPropertyBorderLeftStyle,
133     CSSPropertyBorderLeftWidth,
134     CSSPropertyBorderRightColor,
135     CSSPropertyBorderRightStyle,
136     CSSPropertyBorderRightWidth,
137     CSSPropertyBorderTopColor,
138     CSSPropertyBorderTopLeftRadius,
139     CSSPropertyBorderTopRightRadius,
140     CSSPropertyBorderTopStyle,
141     CSSPropertyBorderTopWidth,
142     CSSPropertyBottom,
143     CSSPropertyBoxShadow,
144     CSSPropertyBoxSizing,
145     CSSPropertyCaptionSide,
146     CSSPropertyClear,
147     CSSPropertyClip,
148     CSSPropertyColor,
149     CSSPropertyContent,
150     CSSPropertyCursor,
151     CSSPropertyDirection,
152     CSSPropertyDisplay,
153     CSSPropertyEmptyCells,
154     CSSPropertyFloat,
155     CSSPropertyFontFamily,
156     CSSPropertyFontSize,
157     CSSPropertyFontStyle,
158     CSSPropertyFontSynthesis,
159     CSSPropertyFontVariant,
160     CSSPropertyFontWeight,
161     CSSPropertyHeight,
162 #if ENABLE(CSS_IMAGE_ORIENTATION)
163     CSSPropertyImageOrientation,
164 #endif
165     CSSPropertyImageRendering,
166 #if ENABLE(CSS_IMAGE_RESOLUTION)
167     CSSPropertyImageResolution,
168 #endif
169     CSSPropertyLeft,
170     CSSPropertyLetterSpacing,
171     CSSPropertyLineHeight,
172     CSSPropertyListStyleImage,
173     CSSPropertyListStylePosition,
174     CSSPropertyListStyleType,
175     CSSPropertyMarginBottom,
176     CSSPropertyMarginLeft,
177     CSSPropertyMarginRight,
178     CSSPropertyMarginTop,
179     CSSPropertyMaxHeight,
180     CSSPropertyMaxWidth,
181     CSSPropertyMinHeight,
182     CSSPropertyMinWidth,
183     CSSPropertyOpacity,
184     CSSPropertyOrphans,
185     CSSPropertyOutlineColor,
186     CSSPropertyOutlineOffset,
187     CSSPropertyOutlineStyle,
188     CSSPropertyOutlineWidth,
189     CSSPropertyOverflowWrap,
190     CSSPropertyOverflowX,
191     CSSPropertyOverflowY,
192     CSSPropertyPaddingBottom,
193     CSSPropertyPaddingLeft,
194     CSSPropertyPaddingRight,
195     CSSPropertyPaddingTop,
196     CSSPropertyPageBreakAfter,
197     CSSPropertyPageBreakBefore,
198     CSSPropertyPageBreakInside,
199     CSSPropertyPointerEvents,
200     CSSPropertyPosition,
201     CSSPropertyResize,
202     CSSPropertyRight,
203     CSSPropertySpeak,
204     CSSPropertyTableLayout,
205     CSSPropertyTabSize,
206     CSSPropertyTextAlign,
207     CSSPropertyTextDecoration,
208 #if ENABLE(CSS3_TEXT)
209     CSSPropertyWebkitTextAlignLast,
210     CSSPropertyWebkitTextJustify,
211 #endif // CSS3_TEXT
212     CSSPropertyWebkitTextDecorationLine,
213     CSSPropertyWebkitTextDecorationStyle,
214     CSSPropertyWebkitTextDecorationColor,
215     CSSPropertyWebkitTextDecorationSkip,
216     CSSPropertyWebkitTextUnderlinePosition,
217     CSSPropertyTextIndent,
218     CSSPropertyTextRendering,
219     CSSPropertyTextShadow,
220     CSSPropertyTextOverflow,
221     CSSPropertyTextTransform,
222     CSSPropertyTop,
223     CSSPropertyTransform,
224     CSSPropertyTransformOrigin,
225     CSSPropertyTransformStyle,
226     CSSPropertyTransitionDelay,
227     CSSPropertyTransitionDuration,
228     CSSPropertyTransitionProperty,
229     CSSPropertyTransitionTimingFunction,
230     CSSPropertyUnicodeBidi,
231     CSSPropertyVerticalAlign,
232     CSSPropertyVisibility,
233     CSSPropertyWhiteSpace,
234     CSSPropertyWidows,
235     CSSPropertyWidth,
236     CSSPropertyWordBreak,
237     CSSPropertyWordSpacing,
238     CSSPropertyWordWrap,
239 #if ENABLE(CSS_SCROLL_SNAP)
240     CSSPropertyWebkitScrollSnapType,
241     CSSPropertyWebkitScrollSnapPointsX,
242     CSSPropertyWebkitScrollSnapPointsY,
243     CSSPropertyWebkitScrollSnapDestination,
244     CSSPropertyWebkitScrollSnapCoordinate,
245 #endif
246     CSSPropertyZIndex,
247     CSSPropertyZoom,
248     CSSPropertyWebkitAnimationDelay,
249     CSSPropertyWebkitAnimationDirection,
250     CSSPropertyWebkitAnimationDuration,
251     CSSPropertyWebkitAnimationFillMode,
252     CSSPropertyWebkitAnimationIterationCount,
253     CSSPropertyWebkitAnimationName,
254     CSSPropertyWebkitAnimationPlayState,
255     CSSPropertyWebkitAnimationTimingFunction,
256 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
257     CSSPropertyWebkitAnimationTrigger,
258 #endif
259     CSSPropertyWebkitAppearance,
260     CSSPropertyWebkitBackfaceVisibility,
261     CSSPropertyWebkitBackgroundClip,
262     CSSPropertyWebkitBackgroundComposite,
263     CSSPropertyWebkitBackgroundOrigin,
264     CSSPropertyWebkitBackgroundSize,
265 #if ENABLE(CSS_COMPOSITING)
266     CSSPropertyMixBlendMode,
267     CSSPropertyIsolation,
268 #endif
269     CSSPropertyWebkitBorderFit,
270     CSSPropertyWebkitBorderHorizontalSpacing,
271     CSSPropertyWebkitBorderImage,
272     CSSPropertyWebkitBorderVerticalSpacing,
273     CSSPropertyWebkitBoxAlign,
274 #if ENABLE(CSS_BOX_DECORATION_BREAK)
275     CSSPropertyWebkitBoxDecorationBreak,
276 #endif
277     CSSPropertyWebkitBoxDirection,
278     CSSPropertyWebkitBoxFlex,
279     CSSPropertyWebkitBoxFlexGroup,
280     CSSPropertyWebkitBoxLines,
281     CSSPropertyWebkitBoxOrdinalGroup,
282     CSSPropertyWebkitBoxOrient,
283     CSSPropertyWebkitBoxPack,
284     CSSPropertyWebkitBoxReflect,
285     CSSPropertyWebkitBoxShadow,
286     CSSPropertyWebkitClipPath,
287     CSSPropertyWebkitColumnBreakAfter,
288     CSSPropertyWebkitColumnBreakBefore,
289     CSSPropertyWebkitColumnBreakInside,
290     CSSPropertyWebkitColumnAxis,
291     CSSPropertyColumnCount,
292     CSSPropertyColumnFill,
293     CSSPropertyColumnGap,
294     CSSPropertyColumnProgression,
295     CSSPropertyColumnRuleColor,
296     CSSPropertyColumnRuleStyle,
297     CSSPropertyColumnRuleWidth,
298     CSSPropertyColumnSpan,
299     CSSPropertyColumnWidth,
300 #if ENABLE(CURSOR_VISIBILITY)
301     CSSPropertyWebkitCursorVisibility,
302 #endif
303 #if ENABLE(DASHBOARD_SUPPORT)
304     CSSPropertyWebkitDashboardRegion,
305 #endif
306     CSSPropertyAlignContent,
307     CSSPropertyAlignItems,
308     CSSPropertyAlignSelf,
309     CSSPropertyFilter,
310     CSSPropertyFlexBasis,
311     CSSPropertyFlexGrow,
312     CSSPropertyFlexShrink,
313     CSSPropertyFlexDirection,
314     CSSPropertyFlexWrap,
315     CSSPropertyJustifyContent,
316     CSSPropertyJustifySelf,
317     CSSPropertyJustifyItems,
318 #if ENABLE(FILTERS_LEVEL_2)
319     CSSPropertyWebkitBackdropFilter,
320 #endif
321     CSSPropertyWebkitFontKerning,
322     CSSPropertyWebkitFontSmoothing,
323     CSSPropertyFontVariantLigatures,
324     CSSPropertyFontVariantPosition,
325     CSSPropertyFontVariantCaps,
326     CSSPropertyFontVariantNumeric,
327     CSSPropertyFontVariantAlternates,
328     CSSPropertyFontVariantEastAsian,
329 #if ENABLE(CSS_GRID_LAYOUT)
330     CSSPropertyWebkitGridAutoColumns,
331     CSSPropertyWebkitGridAutoFlow,
332     CSSPropertyWebkitGridAutoRows,
333     CSSPropertyWebkitGridColumnEnd,
334     CSSPropertyWebkitGridColumnStart,
335     CSSPropertyWebkitGridTemplateAreas,
336     CSSPropertyWebkitGridTemplateColumns,
337     CSSPropertyWebkitGridTemplateRows,
338     CSSPropertyWebkitGridRowEnd,
339     CSSPropertyWebkitGridRowStart,
340 #endif
341     CSSPropertyWebkitHyphenateCharacter,
342     CSSPropertyWebkitHyphenateLimitAfter,
343     CSSPropertyWebkitHyphenateLimitBefore,
344     CSSPropertyWebkitHyphenateLimitLines,
345     CSSPropertyWebkitHyphens,
346     CSSPropertyWebkitInitialLetter,
347     CSSPropertyWebkitLineAlign,
348     CSSPropertyWebkitLineBoxContain,
349     CSSPropertyWebkitLineBreak,
350     CSSPropertyWebkitLineClamp,
351     CSSPropertyWebkitLineGrid,
352     CSSPropertyWebkitLineSnap,
353     CSSPropertyWebkitLocale,
354     CSSPropertyWebkitMarginBeforeCollapse,
355     CSSPropertyWebkitMarginAfterCollapse,
356     CSSPropertyWebkitMarqueeDirection,
357     CSSPropertyWebkitMarqueeIncrement,
358     CSSPropertyWebkitMarqueeRepetition,
359     CSSPropertyWebkitMarqueeStyle,
360     CSSPropertyWebkitMaskBoxImage,
361     CSSPropertyWebkitMaskBoxImageOutset,
362     CSSPropertyWebkitMaskBoxImageRepeat,
363     CSSPropertyWebkitMaskBoxImageSlice,
364     CSSPropertyWebkitMaskBoxImageSource,
365     CSSPropertyWebkitMaskBoxImageWidth,
366     CSSPropertyWebkitMaskClip,
367     CSSPropertyWebkitMaskComposite,
368     CSSPropertyWebkitMaskImage,
369     CSSPropertyWebkitMaskOrigin,
370     CSSPropertyWebkitMaskPosition,
371     CSSPropertyWebkitMaskRepeat,
372     CSSPropertyWebkitMaskSize,
373     CSSPropertyWebkitMaskSourceType,
374     CSSPropertyWebkitNbspMode,
375     CSSPropertyOrder,
376 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
377     CSSPropertyWebkitOverflowScrolling,
378 #endif
379     CSSPropertyPerspective,
380     CSSPropertyPerspectiveOrigin,
381     CSSPropertyWebkitPrintColorAdjust,
382     CSSPropertyWebkitRtlOrdering,
383 #if PLATFORM(IOS)
384     CSSPropertyWebkitTouchCallout,
385 #endif
386 #if ENABLE(CSS_SHAPES)
387     CSSPropertyWebkitShapeOutside,
388 #endif
389 #if ENABLE(TOUCH_EVENTS)
390     CSSPropertyWebkitTapHighlightColor,
391 #endif
392     CSSPropertyWebkitTextCombine,
393     CSSPropertyWebkitTextDecorationsInEffect,
394     CSSPropertyWebkitTextEmphasisColor,
395     CSSPropertyWebkitTextEmphasisPosition,
396     CSSPropertyWebkitTextEmphasisStyle,
397     CSSPropertyWebkitTextFillColor,
398     CSSPropertyWebkitTextOrientation,
399     CSSPropertyWebkitTextSecurity,
400 #if ENABLE(IOS_TEXT_AUTOSIZING)
401     CSSPropertyWebkitTextSizeAdjust,
402 #endif
403     CSSPropertyWebkitTextStrokeColor,
404     CSSPropertyWebkitTextStrokeWidth,
405     CSSPropertyWebkitTextZoom,
406     CSSPropertyWebkitTransformStyle,
407     CSSPropertyWebkitTransitionDelay,
408     CSSPropertyWebkitTransitionDuration,
409     CSSPropertyWebkitTransitionProperty,
410     CSSPropertyWebkitTransitionTimingFunction,
411     CSSPropertyWebkitUserDrag,
412     CSSPropertyWebkitUserModify,
413     CSSPropertyWebkitUserSelect,
414     CSSPropertyWebkitWritingMode,
415 #if ENABLE(CSS_REGIONS)
416     CSSPropertyWebkitFlowInto,
417     CSSPropertyWebkitFlowFrom,
418     CSSPropertyWebkitRegionBreakAfter,
419     CSSPropertyWebkitRegionBreakBefore,
420     CSSPropertyWebkitRegionBreakInside,
421     CSSPropertyWebkitRegionFragment,
422 #endif
423 #if ENABLE(CSS_SHAPES)
424     CSSPropertyWebkitShapeMargin,
425     CSSPropertyWebkitShapeImageThreshold,
426 #endif
427     CSSPropertyBufferedRendering,
428     CSSPropertyClipPath,
429     CSSPropertyClipRule,
430     CSSPropertyCx,
431     CSSPropertyCy,
432     CSSPropertyMask,
433     CSSPropertyFilter,
434     CSSPropertyFloodColor,
435     CSSPropertyFloodOpacity,
436     CSSPropertyLightingColor,
437     CSSPropertyStopColor,
438     CSSPropertyStopOpacity,
439     CSSPropertyColorInterpolation,
440     CSSPropertyColorInterpolationFilters,
441     CSSPropertyColorRendering,
442     CSSPropertyFill,
443     CSSPropertyFillOpacity,
444     CSSPropertyFillRule,
445     CSSPropertyMarkerEnd,
446     CSSPropertyMarkerMid,
447     CSSPropertyMarkerStart,
448     CSSPropertyMaskType,
449     CSSPropertyPaintOrder,
450     CSSPropertyR,
451     CSSPropertyRx,
452     CSSPropertyRy,
453     CSSPropertyShapeRendering,
454     CSSPropertyStroke,
455     CSSPropertyStrokeDasharray,
456     CSSPropertyStrokeDashoffset,
457     CSSPropertyStrokeLinecap,
458     CSSPropertyStrokeLinejoin,
459     CSSPropertyStrokeMiterlimit,
460     CSSPropertyStrokeOpacity,
461     CSSPropertyStrokeWidth,
462     CSSPropertyAlignmentBaseline,
463     CSSPropertyBaselineShift,
464     CSSPropertyDominantBaseline,
465     CSSPropertyKerning,
466     CSSPropertyTextAnchor,
467     CSSPropertyWritingMode,
468     CSSPropertyGlyphOrientationHorizontal,
469     CSSPropertyGlyphOrientationVertical,
470     CSSPropertyWebkitSvgShadow,
471     CSSPropertyVectorEffect,
472     CSSPropertyX,
473     CSSPropertyY
474 };
475
476 const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties);
477
478 static CSSValueID valueForRepeatRule(int rule)
479 {
480     switch (rule) {
481         case RepeatImageRule:
482             return CSSValueRepeat;
483         case RoundImageRule:
484             return CSSValueRound;
485         case SpaceImageRule:
486             return CSSValueSpace;
487         default:
488             return CSSValueStretch;
489     }
490 }
491
492 static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length)
493 {
494     // These values can be percentages, numbers, or while an animation of mixed types is in progress,
495     // a calculation that combines a percentage and a number.
496     if (length.isPercent())
497         return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
498     if (length.isFixed())
499         return CSSValuePool::singleton().createValue(length.value(), CSSPrimitiveValue::CSS_NUMBER);
500
501     // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage.
502     // And even if we could do that, it's not clear if that's exactly what we'd want during animation.
503     // FIXME: For now, just return 0.
504     ASSERT(length.isCalculated());
505     return CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
506 }
507
508 static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
509 {
510     auto& slices = image.imageSlices();
511
512     RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top());
513
514     RefPtr<CSSPrimitiveValue> right;
515     RefPtr<CSSPrimitiveValue> bottom;
516     RefPtr<CSSPrimitiveValue> left;
517
518     if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) {
519         right = top;
520         bottom = top;
521         left = top;
522     } else {
523         right = valueForImageSliceSide(slices.right());
524
525         if (slices.bottom() == slices.top() && slices.right() == slices.left()) {
526             bottom = top;
527             left = right;
528         } else {
529             bottom = valueForImageSliceSide(slices.bottom());
530
531             if (slices.left() == slices.right())
532                 left = right;
533             else
534                 left = valueForImageSliceSide(slices.left());
535         }
536     }
537
538     auto quad = Quad::create();
539     quad->setTop(top.release());
540     quad->setRight(right.release());
541     quad->setBottom(bottom.release());
542     quad->setLeft(left.release());
543
544     return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTF::move(quad)), image.fill());
545 }
546
547 static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box)
548 {
549     RefPtr<CSSPrimitiveValue> top;
550     RefPtr<CSSPrimitiveValue> right;
551     RefPtr<CSSPrimitiveValue> bottom;
552     RefPtr<CSSPrimitiveValue> left;
553
554     auto& cssValuePool = CSSValuePool::singleton();
555
556     if (box.top().isRelative())
557         top = cssValuePool.createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER);
558     else
559         top = cssValuePool.createValue(box.top());
560
561     if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) {
562         right = top;
563         bottom = top;
564         left = top;
565     } else {
566         if (box.right().isRelative())
567             right = cssValuePool.createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER);
568         else
569             right = cssValuePool.createValue(box.right());
570
571         if (box.bottom() == box.top() && box.right() == box.left()) {
572             bottom = top;
573             left = right;
574         } else {
575             if (box.bottom().isRelative())
576                 bottom = cssValuePool.createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
577             else
578                 bottom = cssValuePool.createValue(box.bottom());
579
580             if (box.left() == box.right())
581                 left = right;
582             else {
583                 if (box.left().isRelative())
584                     left = cssValuePool.createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER);
585                 else
586                     left = cssValuePool.createValue(box.left());
587             }
588         }
589     }
590
591     auto quad = Quad::create();
592     quad->setTop(top);
593     quad->setRight(right);
594     quad->setBottom(bottom);
595     quad->setLeft(left);
596
597     return cssValuePool.createValue(WTF::move(quad));
598 }
599
600 static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
601 {
602     auto& cssValuePool = CSSValuePool::singleton();
603     RefPtr<CSSPrimitiveValue> horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
604
605     RefPtr<CSSPrimitiveValue> verticalRepeat;
606     if (image.horizontalRule() == image.verticalRule())
607         verticalRepeat = horizontalRepeat;
608     else
609         verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule()));
610     return cssValuePool.createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release()));
611 }
612
613 static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
614 {
615     if (!image.hasImage())
616         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
617
618     // Image first.
619     RefPtr<CSSValue> imageValue;
620     if (image.image())
621         imageValue = image.image()->cssValue();
622
623     // Create the image slice.
624     RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
625
626     // Create the border area slices.
627     RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices());
628
629     // Create the border outset.
630     RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset());
631
632     // Create the repeat rules.
633     RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
634
635     return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
636 }
637
638 inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
639 {
640     return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
641 }
642
643 inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
644 {
645     return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
646 }
647
648 static Ref<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
649 {
650     if (length.isFixed())
651         return zoomAdjustedPixelValue(length.value(), style);
652     return CSSValuePool::singleton().createValue(length, style);
653 }
654
655 static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
656 {
657     if (!reflection)
658         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
659
660     RefPtr<CSSPrimitiveValue> offset;
661     if (reflection->offset().isPercentOrCalculated())
662         offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
663     else
664         offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
665
666     RefPtr<CSSPrimitiveValue> direction;
667     switch (reflection->direction()) {
668     case ReflectionBelow:
669         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow);
670         break;
671     case ReflectionAbove:
672         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove);
673         break;
674     case ReflectionLeft:
675         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft);
676         break;
677     case ReflectionRight:
678         direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight);
679         break;
680     }
681
682     return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask()));
683 }
684
685 static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
686 {
687     auto positionList = CSSValueList::createSpaceSeparated();
688     if (layer->isBackgroundOriginSet()) {
689         ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
690         positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundXOrigin()));
691     }
692     positionList.get().append(zoomAdjustedPixelValueForLength(layer->xPosition(), style));
693     if (layer->isBackgroundOriginSet()) {
694         ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
695         positionList.get().append(CSSValuePool::singleton().createValue(layer->backgroundYOrigin()));
696     }
697     positionList.get().append(zoomAdjustedPixelValueForLength(layer->yPosition(), style));
698     return positionList;
699 }
700
701 static RefPtr<CSSValue> positionOffsetValue(RenderStyle& style, CSSPropertyID propertyID)
702 {
703     Length length;
704     switch (propertyID) {
705         case CSSPropertyLeft:
706             length = style.left();
707             break;
708         case CSSPropertyRight:
709             length = style.right();
710             break;
711         case CSSPropertyTop:
712             length = style.top();
713             break;
714         case CSSPropertyBottom:
715             length = style.bottom();
716             break;
717         default:
718             return nullptr;
719     }
720
721     if (style.hasOutOfFlowPosition()) {
722         if (length.isFixed())
723             return zoomAdjustedPixelValue(length.value(), style);
724
725         return CSSValuePool::singleton().createValue(length);
726     }
727
728     if (style.hasInFlowPosition()) {
729         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
730         // In other words if left is auto and right is not auto, then left's computed value is negative right().
731         // So we should get the opposite length unit and see if it is auto.
732         return CSSValuePool::singleton().createValue(length);
733     }
734
735     return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
736 }
737
738 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::currentColorOrValidColor(RenderStyle* style, const Color& color) const
739 {
740     // This function does NOT look at visited information, so that computed style doesn't expose that.
741     if (!color.isValid())
742         return CSSValuePool::singleton().createColorValue(style->color().rgb());
743     return CSSValuePool::singleton().createColorValue(color.rgb());
744 }
745
746 static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style)
747 {
748     if (length.isPercent())
749         return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
750     
751     return zoomAdjustedPixelValue(valueForLength(length, 0), style);
752 }
753
754 static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style)
755 {
756     if (length.isAuto())
757         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
758
759     return zoomAdjustedPixelValue(valueForLength(length, 0), style);
760 }
761
762 static Ref<CSSValueList> getBorderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style)
763 {
764     auto list = CSSValueList::createSpaceSeparated();
765     list.get().append(percentageOrZoomAdjustedValue(radius.width(), style));
766     list.get().append(percentageOrZoomAdjustedValue(radius.height(), style));
767     return list;
768 }
769
770 static Ref<CSSValue> getBorderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style)
771 {
772     if (radius.width() == radius.height())
773         return percentageOrZoomAdjustedValue(radius.width(), style);
774
775     return getBorderRadiusCornerValues(radius, style);
776 }
777
778 static Ref<CSSValueList> getBorderRadiusShorthandValue(const RenderStyle& style)
779 {
780     auto list = CSSValueList::createSlashSeparated();
781     bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width();
782     bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width());
783     bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width() != style.borderTopLeftRadius().width());
784
785     bool showVerticalBottomLeft = style.borderTopRightRadius().height() != style.borderBottomLeftRadius().height();
786     bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height());
787     bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height());
788
789     RefPtr<CSSValueList> topLeftRadius = getBorderRadiusCornerValues(style.borderTopLeftRadius(), style);
790     RefPtr<CSSValueList> topRightRadius = getBorderRadiusCornerValues(style.borderTopRightRadius(), style);
791     RefPtr<CSSValueList> bottomRightRadius = getBorderRadiusCornerValues(style.borderBottomRightRadius(), style);
792     RefPtr<CSSValueList> bottomLeftRadius = getBorderRadiusCornerValues(style.borderBottomLeftRadius(), style);
793
794     RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
795     horizontalRadii->append(*topLeftRadius->item(0));
796     if (showHorizontalTopRight)
797         horizontalRadii->append(*topRightRadius->item(0));
798     if (showHorizontalBottomRight)
799         horizontalRadii->append(*bottomRightRadius->item(0));
800     if (showHorizontalBottomLeft)
801         horizontalRadii->append(*bottomLeftRadius->item(0));
802
803     list.get().append(horizontalRadii.releaseNonNull());
804
805     RefPtr<CSSValueList> verticalRadiiList = CSSValueList::createSpaceSeparated();
806     verticalRadiiList->append(*topLeftRadius->item(1));
807     if (showVerticalTopRight)
808         verticalRadiiList->append(*topRightRadius->item(1));
809     if (showVerticalBottomRight)
810         verticalRadiiList->append(*bottomRightRadius->item(1));
811     if (showVerticalBottomLeft)
812         verticalRadiiList->append(*bottomLeftRadius->item(1));
813
814     if (!verticalRadiiList->equals(downcast<CSSValueList>(*list.get().item(0))))
815         list.get().append(verticalRadiiList.releaseNonNull());
816
817     return list;
818 }
819
820 static LayoutRect sizingBox(RenderObject& renderer)
821 {
822     if (!is<RenderBox>(renderer))
823         return LayoutRect();
824
825     auto& box = downcast<RenderBox>(renderer);
826     return box.style().boxSizing() == BORDER_BOX ? box.borderBoxRect() : box.computedCSSContentBoxRect();
827 }
828
829 static Ref<WebKitCSSTransformValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style)
830 {
831     RefPtr<WebKitCSSTransformValue> transformValue;
832     auto& cssValuePool = CSSValuePool::singleton();
833     if (transform.isAffine()) {
834         transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
835
836         transformValue->append(cssValuePool.createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
837         transformValue->append(cssValuePool.createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
838         transformValue->append(cssValuePool.createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
839         transformValue->append(cssValuePool.createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
840         transformValue->append(zoomAdjustedNumberValue(transform.e(), style));
841         transformValue->append(zoomAdjustedNumberValue(transform.f(), style));
842     } else {
843         transformValue = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
844
845         transformValue->append(cssValuePool.createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
846         transformValue->append(cssValuePool.createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
847         transformValue->append(cssValuePool.createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
848         transformValue->append(cssValuePool.createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
849
850         transformValue->append(cssValuePool.createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
851         transformValue->append(cssValuePool.createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
852         transformValue->append(cssValuePool.createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
853         transformValue->append(cssValuePool.createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
854
855         transformValue->append(cssValuePool.createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
856         transformValue->append(cssValuePool.createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
857         transformValue->append(cssValuePool.createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
858         transformValue->append(cssValuePool.createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
859
860         transformValue->append(zoomAdjustedNumberValue(transform.m41(), style));
861         transformValue->append(zoomAdjustedNumberValue(transform.m42(), style));
862         transformValue->append(zoomAdjustedNumberValue(transform.m43(), style));
863         transformValue->append(cssValuePool.createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
864     }
865
866     return transformValue.releaseNonNull();
867 }
868
869 static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
870 {
871     if (!renderer || !renderer->hasTransform())
872         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
873
874     FloatRect pixelSnappedRect;
875     if (is<RenderBox>(*renderer))
876         pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor());
877
878     TransformationMatrix transform;
879     style.applyTransform(transform, pixelSnappedRect, RenderStyle::ExcludeTransformOrigin);
880     // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design.
881
882     // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
883     auto list = CSSValueList::createSpaceSeparated();
884     list.get().append(matrixTransformValue(transform, style));
885     return WTF::move(list);
886 }
887
888 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
889 {
890     return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSPrimitiveValue::CSS_PX);
891 }
892
893 static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
894 {
895     return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length);
896 }
897
898 Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust)
899 {
900     auto& cssValuePool = CSSValuePool::singleton();
901     if (!shadow)
902         return cssValuePool.createIdentifierValue(CSSValueNone);
903
904     auto list = CSSValueList::createCommaSeparated();
905     for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) {
906         RefPtr<CSSPrimitiveValue> x = adjustLengthForZoom(currShadowData->x(), style, adjust);
907         RefPtr<CSSPrimitiveValue> y = adjustLengthForZoom(currShadowData->y(), style, adjust);
908         RefPtr<CSSPrimitiveValue> blur = adjustLengthForZoom(currShadowData->radius(), style, adjust);
909         RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? PassRefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust);
910         RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset);
911         RefPtr<CSSPrimitiveValue> color = cssValuePool.createColorValue(currShadowData->color().rgb());
912         list.get().prepend(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
913     }
914     return WTF::move(list);
915 }
916
917 Ref<CSSValue> ComputedStyleExtractor::valueForFilter(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust)
918 {
919     auto& cssValuePool = CSSValuePool::singleton();
920     if (filterOperations.operations().isEmpty())
921         return cssValuePool.createIdentifierValue(CSSValueNone);
922
923     auto list = CSSValueList::createSpaceSeparated();
924
925     RefPtr<WebKitCSSFilterValue> filterValue;
926
927     Vector<RefPtr<FilterOperation>>::const_iterator end = filterOperations.operations().end();
928     for (Vector<RefPtr<FilterOperation>>::const_iterator it = filterOperations.operations().begin(); it != end; ++it) {
929         FilterOperation& filterOperation = **it;
930         switch (filterOperation.type()) {
931         case FilterOperation::REFERENCE: {
932             ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
933             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ReferenceFilterOperation);
934             filterValue->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI));
935             break;
936         }
937         case FilterOperation::GRAYSCALE: {
938             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
939             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::GrayscaleFilterOperation);
940             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
941             break;
942         }
943         case FilterOperation::SEPIA: {
944             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
945             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SepiaFilterOperation);
946             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
947             break;
948         }
949         case FilterOperation::SATURATE: {
950             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
951             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::SaturateFilterOperation);
952             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
953             break;
954         }
955         case FilterOperation::HUE_ROTATE: {
956             BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
957             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::HueRotateFilterOperation);
958             filterValue->append(cssValuePool.createValue(colorMatrixOperation.amount(), CSSPrimitiveValue::CSS_DEG));
959             break;
960         }
961         case FilterOperation::INVERT: {
962             BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
963             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::InvertFilterOperation);
964             filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
965             break;
966         }
967         case FilterOperation::OPACITY: {
968             BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
969             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::OpacityFilterOperation);
970             filterValue->append(cssValuePool.createValue(componentTransferOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
971             break;
972         }
973         case FilterOperation::BRIGHTNESS: {
974             BasicComponentTransferFilterOperation& brightnessOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
975             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BrightnessFilterOperation);
976             filterValue->append(cssValuePool.createValue(brightnessOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
977             break;
978         }
979         case FilterOperation::CONTRAST: {
980             BasicComponentTransferFilterOperation& contrastOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
981             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::ContrastFilterOperation);
982             filterValue->append(cssValuePool.createValue(contrastOperation.amount(), CSSPrimitiveValue::CSS_NUMBER));
983             break;
984         }
985         case FilterOperation::BLUR: {
986             BlurFilterOperation& blurOperation = downcast<BlurFilterOperation>(filterOperation);
987             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::BlurFilterOperation);
988             filterValue->append(adjustLengthForZoom(blurOperation.stdDeviation(), style, adjust));
989             break;
990         }
991         case FilterOperation::DROP_SHADOW: {
992             DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
993             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::DropShadowFilterOperation);
994             // We want our computed style to look like that of a text shadow (has neither spread nor inset style).
995             ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color());
996             filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust));
997             break;
998         }
999         default:
1000             filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::UnknownFilterOperation);
1001             break;
1002         }
1003         list.get().append(filterValue.releaseNonNull());
1004     }
1005
1006     return WTF::move(list);
1007 }
1008
1009 #if ENABLE(CSS_GRID_LAYOUT)
1010 static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
1011 {
1012     if (!trackBreadth.isLength())
1013         return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
1014
1015     const Length& trackBreadthLength = trackBreadth.length();
1016     if (trackBreadthLength.isAuto())
1017         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1018     return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
1019 }
1020
1021 static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
1022 {
1023     switch (trackSize.type()) {
1024     case LengthTrackSizing:
1025         return specifiedValueForGridTrackBreadth(trackSize.length(), style);
1026     default:
1027         ASSERT(trackSize.type() == MinMaxTrackSizing);
1028         RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
1029         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
1030         minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
1031         return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
1032     }
1033 }
1034
1035 static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLinesMap& orderedNamedGridLines, size_t i, CSSValueList& list)
1036 {
1037     const Vector<String>& namedGridLines = orderedNamedGridLines.get(i);
1038     if (namedGridLines.isEmpty())
1039         return;
1040
1041     auto& cssValuePool = CSSValuePool::singleton();
1042     RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
1043     for (auto& name : namedGridLines)
1044         lineNames->append(cssValuePool.createValue(name, CSSPrimitiveValue::CSS_STRING));
1045     list.append(lineNames.releaseNonNull());
1046 }
1047
1048 static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
1049 {
1050     const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridColumns() : style.gridRows();
1051     const OrderedNamedGridLinesMap& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
1052     bool isRenderGrid = is<RenderGrid>(renderer);
1053
1054     // Handle the 'none' case.
1055     bool trackListIsEmpty = trackSizes.isEmpty();
1056     if (isRenderGrid && trackListIsEmpty) {
1057         // For grids we should consider every listed track, whether implicitly or explicitly created. If we don't have
1058         // any explicit track and there are no children then there are no implicit tracks. We cannot simply check the
1059         // number of rows/columns in our internal grid representation because it's always at least 1x1 (see r143331).
1060         trackListIsEmpty = !downcast<RenderBlock>(*renderer).firstChild();
1061     }
1062
1063     if (trackListIsEmpty) {
1064         ASSERT(orderedNamedGridLines.isEmpty());
1065         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1066     }
1067
1068     auto list = CSSValueList::createSpaceSeparated();
1069     unsigned insertionIndex;
1070     if (isRenderGrid) {
1071         const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? downcast<RenderGrid>(*renderer).columnPositions() : downcast<RenderGrid>(*renderer).rowPositions();
1072         // There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
1073         // so we'll have more trackPositions than trackSizes as the latter only contain the explicit grid.
1074         ASSERT(trackPositions.size() - 1 >= trackSizes.size());
1075
1076         for (unsigned i = 0; i < trackPositions.size() - 1; ++i) {
1077             addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
1078             list.get().append(zoomAdjustedPixelValue(trackPositions[i + 1] - trackPositions[i], style));
1079         }
1080         insertionIndex = trackPositions.size() - 1;
1081     } else {
1082         for (unsigned i = 0; i < trackSizes.size(); ++i) {
1083             addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, list.get());
1084             list.get().append(specifiedValueForGridTrackSize(trackSizes[i], style));
1085         }
1086         insertionIndex = trackSizes.size();
1087     }
1088
1089     // Those are the trailing <ident>* allowed in the syntax.
1090     addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, insertionIndex, list.get());
1091     return WTF::move(list);
1092 }
1093
1094 static Ref<CSSValue> valueForGridPosition(const GridPosition& position)
1095 {
1096     auto& cssValuePool = CSSValuePool::singleton();
1097     if (position.isAuto())
1098         return cssValuePool.createIdentifierValue(CSSValueAuto);
1099
1100     if (position.isNamedGridArea())
1101         return cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
1102
1103     auto list = CSSValueList::createSpaceSeparated();
1104     if (position.isSpan()) {
1105         list.get().append(cssValuePool.createIdentifierValue(CSSValueSpan));
1106         list.get().append(cssValuePool.createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
1107     } else
1108         list.get().append(cssValuePool.createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER));
1109
1110     if (!position.namedGridLine().isNull())
1111         list.get().append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
1112     return WTF::move(list);
1113 }
1114 #endif
1115
1116 static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation)
1117 {
1118     if (animation.animationMode() == Animation::AnimateNone)
1119         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1120     if (animation.animationMode() == Animation::AnimateAll)
1121         return CSSValuePool::singleton().createIdentifierValue(CSSValueAll);
1122     return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING);
1123 }
1124
1125 static Ref<CSSValueList> getTransitionPropertyValue(const AnimationList* animList)
1126 {
1127     auto list = CSSValueList::createCommaSeparated();
1128     if (animList) {
1129         for (size_t i = 0; i < animList->size(); ++i)
1130             list.get().append(createTransitionPropertyValue(animList->animation(i)));
1131     } else
1132         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll));
1133     return list;
1134 }
1135
1136 #if ENABLE(CSS_SCROLL_SNAP)
1137 static Ref<CSSValueList> scrollSnapDestination(RenderStyle& style, const LengthSize& destination)
1138 {
1139     auto list = CSSValueList::createSpaceSeparated();
1140     list.get().append(zoomAdjustedPixelValueForLength(destination.width(), style));
1141     list.get().append(zoomAdjustedPixelValueForLength(destination.height(), style));
1142     return list;
1143 }
1144
1145 static Ref<CSSValue> scrollSnapPoints(RenderStyle& style, const ScrollSnapPoints* points)
1146 {
1147     if (!points)
1148         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1149
1150     if (points->usesElements)
1151         return CSSValuePool::singleton().createIdentifierValue(CSSValueElements);
1152     auto list = CSSValueList::createSpaceSeparated();
1153     for (auto& point : points->offsets)
1154         list.get().append(zoomAdjustedPixelValueForLength(point, style));
1155     if (points->hasRepeat)
1156         list.get().append(CSSValuePool::singleton().createValue(LengthRepeat::create(zoomAdjustedPixelValueForLength(points->repeatOffset, style))));
1157     return WTF::move(list);
1158 }
1159
1160 static Ref<CSSValue> scrollSnapCoordinates(RenderStyle& style, const Vector<LengthSize>& coordinates)
1161 {
1162     if (coordinates.isEmpty())
1163         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1164
1165     auto list = CSSValueList::createCommaSeparated();
1166
1167     for (auto& coordinate : coordinates) {
1168         auto pair = CSSValueList::createSpaceSeparated();
1169         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.width(), style));
1170         pair.get().append(zoomAdjustedPixelValueForLength(coordinate.height(), style));
1171         list.get().append(WTF::move(pair));
1172     }
1173
1174     return WTF::move(list);
1175 }
1176 #endif
1177
1178 static Ref<CSSValue> getWillChangePropertyValue(const WillChangeData* willChangeData)
1179 {
1180     auto& cssValuePool = CSSValuePool::singleton();
1181     if (!willChangeData || !willChangeData->numFeatures())
1182         return cssValuePool.createIdentifierValue(CSSValueAuto);
1183
1184     auto list = CSSValueList::createCommaSeparated();
1185     for (size_t i = 0; i < willChangeData->numFeatures(); ++i) {
1186         WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i);
1187         switch (feature.first) {
1188         case WillChangeData::ScrollPosition:
1189             list.get().append(cssValuePool.createIdentifierValue(CSSValueScrollPosition));
1190             break;
1191         case WillChangeData::Contents:
1192             list.get().append(cssValuePool.createIdentifierValue(CSSValueContents));
1193             break;
1194         case WillChangeData::Property:
1195             list.get().append(cssValuePool.createIdentifierValue(feature.second));
1196             break;
1197         case WillChangeData::Invalid:
1198             ASSERT_NOT_REACHED();
1199             break;
1200         }
1201     }
1202
1203     return WTF::move(list);
1204 }
1205
1206 static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
1207 {
1208     switch (value) {
1209     case FontVariantLigatures::Normal:
1210         return;
1211     case FontVariantLigatures::No:
1212         list.append(CSSValuePool::singleton().createIdentifierValue(noValue));
1213         return;
1214     case FontVariantLigatures::Yes:
1215         list.append(CSSValuePool::singleton().createIdentifierValue(yesValue));
1216         return;
1217     }
1218     ASSERT_NOT_REACHED();
1219 }
1220
1221 static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates)
1222 {
1223     auto& cssValuePool = CSSValuePool::singleton();
1224     if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No)
1225         return cssValuePool.createIdentifierValue(CSSValueNone);
1226     if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal)
1227         return cssValuePool.createIdentifierValue(CSSValueNormal);
1228
1229     auto valueList = CSSValueList::createSpaceSeparated();
1230     appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures);
1231     appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
1232     appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
1233     appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
1234     return WTF::move(valueList);
1235 }
1236
1237 static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position)
1238 {
1239     auto& cssValuePool = CSSValuePool::singleton();
1240     CSSValueID valueID = CSSValueNormal;
1241     switch (position) {
1242     case FontVariantPosition::Normal:
1243         break;
1244     case FontVariantPosition::Subscript:
1245         valueID = CSSValueSub;
1246         break;
1247     case FontVariantPosition::Superscript:
1248         valueID = CSSValueSuper;
1249         break;
1250     }
1251     return cssValuePool.createIdentifierValue(valueID);
1252 }
1253
1254 static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps)
1255 {
1256     auto& cssValuePool = CSSValuePool::singleton();
1257     CSSValueID valueID = CSSValueNormal;
1258     switch (caps) {
1259     case FontVariantCaps::Normal:
1260         break;
1261     case FontVariantCaps::Small:
1262         valueID = CSSValueSmallCaps;
1263         break;
1264     case FontVariantCaps::AllSmall:
1265         valueID = CSSValueAllSmallCaps;
1266         break;
1267     case FontVariantCaps::Petite:
1268         valueID = CSSValuePetiteCaps;
1269         break;
1270     case FontVariantCaps::AllPetite:
1271         valueID = CSSValueAllPetiteCaps;
1272         break;
1273     case FontVariantCaps::Unicase:
1274         valueID = CSSValueUnicase;
1275         break;
1276     case FontVariantCaps::Titling:
1277         valueID = CSSValueTitlingCaps;
1278         break;
1279     }
1280     return cssValuePool.createIdentifierValue(valueID);
1281 }
1282
1283 static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero)
1284 {
1285     auto& cssValuePool = CSSValuePool::singleton();
1286     if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal)
1287         return cssValuePool.createIdentifierValue(CSSValueNormal);
1288
1289     auto valueList = CSSValueList::createSpaceSeparated();
1290     switch (figure) {
1291     case FontVariantNumericFigure::Normal:
1292         break;
1293     case FontVariantNumericFigure::LiningNumbers:
1294         valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums));
1295         break;
1296     case FontVariantNumericFigure::OldStyleNumbers:
1297         valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums));
1298         break;
1299     }
1300
1301     switch (spacing) {
1302     case FontVariantNumericSpacing::Normal:
1303         break;
1304     case FontVariantNumericSpacing::ProportionalNumbers:
1305         valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums));
1306         break;
1307     case FontVariantNumericSpacing::TabularNumbers:
1308         valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums));
1309         break;
1310     }
1311
1312     switch (fraction) {
1313     case FontVariantNumericFraction::Normal:
1314         break;
1315     case FontVariantNumericFraction::DiagonalFractions:
1316         valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions));
1317         break;
1318     case FontVariantNumericFraction::StackedFractions:
1319         valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions));
1320         break;
1321     }
1322
1323     if (ordinal == FontVariantNumericOrdinal::Yes)
1324         valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal));
1325     if (slashedZero == FontVariantNumericSlashedZero::Yes)
1326         valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));
1327
1328     return WTF::move(valueList);
1329 }
1330
1331 static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
1332 {
1333     auto& cssValuePool = CSSValuePool::singleton();
1334     CSSValueID valueID = CSSValueNormal;
1335     switch (alternates) {
1336     case FontVariantAlternates::Normal:
1337         break;
1338     case FontVariantAlternates::HistoricalForms:
1339         valueID = CSSValueHistoricalForms;
1340         break;
1341     }
1342     return cssValuePool.createIdentifierValue(valueID);
1343 }
1344
1345 static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby)
1346 {
1347     auto& cssValuePool = CSSValuePool::singleton();
1348     if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal)
1349         return cssValuePool.createIdentifierValue(CSSValueNormal);
1350
1351     auto valueList = CSSValueList::createSpaceSeparated();
1352     switch (variant) {
1353     case FontVariantEastAsianVariant::Normal:
1354         break;
1355     case FontVariantEastAsianVariant::Jis78:
1356         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78));
1357         break;
1358     case FontVariantEastAsianVariant::Jis83:
1359         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83));
1360         break;
1361     case FontVariantEastAsianVariant::Jis90:
1362         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90));
1363         break;
1364     case FontVariantEastAsianVariant::Jis04:
1365         valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04));
1366         break;
1367     case FontVariantEastAsianVariant::Simplified:
1368         valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified));
1369         break;
1370     case FontVariantEastAsianVariant::Traditional:
1371         valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional));
1372         break;
1373     }
1374
1375     switch (width) {
1376     case FontVariantEastAsianWidth::Normal:
1377         break;
1378     case FontVariantEastAsianWidth::FullWidth:
1379         valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
1380         break;
1381     case FontVariantEastAsianWidth::ProportionalWidth:
1382         valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
1383         break;
1384     }
1385
1386     if (ruby == FontVariantEastAsianRuby::Yes)
1387         valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby));
1388
1389     return WTF::move(valueList);
1390 }
1391
1392 static Ref<CSSValueList> getDelayValue(const AnimationList* animList)
1393 {
1394     auto& cssValuePool = CSSValuePool::singleton();
1395     auto list = CSSValueList::createCommaSeparated();
1396     if (animList) {
1397         for (size_t i = 0; i < animList->size(); ++i)
1398             list.get().append(cssValuePool.createValue(animList->animation(i).delay(), CSSPrimitiveValue::CSS_S));
1399     } else {
1400         // Note that initialAnimationDelay() is used for both transitions and animations
1401         list.get().append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
1402     }
1403     return list;
1404 }
1405
1406 static Ref<CSSValueList> getDurationValue(const AnimationList* animList)
1407 {
1408     auto& cssValuePool = CSSValuePool::singleton();
1409     auto list = CSSValueList::createCommaSeparated();
1410     if (animList) {
1411         for (size_t i = 0; i < animList->size(); ++i)
1412             list.get().append(cssValuePool.createValue(animList->animation(i).duration(), CSSPrimitiveValue::CSS_S));
1413     } else {
1414         // Note that initialAnimationDuration() is used for both transitions and animations
1415         list.get().append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
1416     }
1417     return list;
1418 }
1419
1420 static Ref<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
1421 {
1422     switch (timingFunction->type()) {
1423     case TimingFunction::CubicBezierFunction: {
1424         const CubicBezierTimingFunction* bezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(timingFunction);
1425         if (bezierTimingFunction->timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
1426             CSSValueID valueId = CSSValueInvalid;
1427             switch (bezierTimingFunction->timingFunctionPreset()) {
1428             case CubicBezierTimingFunction::Ease:
1429                 valueId = CSSValueEase;
1430                 break;
1431             case CubicBezierTimingFunction::EaseIn:
1432                 valueId = CSSValueEaseIn;
1433                 break;
1434             case CubicBezierTimingFunction::EaseOut:
1435                 valueId = CSSValueEaseOut;
1436                 break;
1437             default:
1438                 ASSERT(bezierTimingFunction->timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut);
1439                 valueId = CSSValueEaseInOut;
1440                 break;
1441             }
1442             return CSSValuePool::singleton().createIdentifierValue(valueId);
1443         }
1444         return CSSCubicBezierTimingFunctionValue::create(bezierTimingFunction->x1(), bezierTimingFunction->y1(), bezierTimingFunction->x2(), bezierTimingFunction->y2());
1445     }
1446     case TimingFunction::StepsFunction: {
1447         const StepsTimingFunction* stepsTimingFunction = static_cast<const StepsTimingFunction*>(timingFunction);
1448         return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
1449     }
1450     default:
1451         ASSERT(timingFunction->type() == TimingFunction::LinearFunction);
1452         return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear);
1453     }
1454 }
1455
1456 static Ref<CSSValueList> getTimingFunctionValue(const AnimationList* animList)
1457 {
1458     auto list = CSSValueList::createCommaSeparated();
1459     if (animList) {
1460         for (size_t i = 0; i < animList->size(); ++i)
1461             list.get().append(createTimingFunctionValue(animList->animation(i).timingFunction().get()));
1462     } else
1463         // Note that initialAnimationTimingFunction() is used for both transitions and animations
1464         list.get().append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
1465     return list;
1466 }
1467
1468 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
1469 static Ref<CSSValue> createAnimationTriggerValue(const AnimationTrigger* trigger, const RenderStyle& style)
1470 {
1471     switch (trigger->type()) {
1472     case AnimationTrigger::AnimationTriggerType::ScrollAnimationTriggerType: {
1473         auto& scrollAnimationTrigger = downcast<ScrollAnimationTrigger>(*trigger);
1474         if (scrollAnimationTrigger.endValue().isAuto())
1475             return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style));
1476         return CSSAnimationTriggerScrollValue::create(zoomAdjustedPixelValueForLength(scrollAnimationTrigger.startValue(), style),
1477                                                       zoomAdjustedPixelValueForLength(scrollAnimationTrigger.endValue(), style));
1478     }
1479     default:
1480         ASSERT(trigger->type() == AnimationTrigger::AnimationTriggerType::AutoAnimationTriggerType);
1481         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1482     }
1483 }
1484
1485 static Ref<CSSValueList> getAnimationTriggerValue(const AnimationList* animList, const RenderStyle& style)
1486 {
1487     auto list = CSSValueList::createCommaSeparated();
1488     if (animList) {
1489         for (size_t i = 0; i < animList->size(); ++i)
1490             list.get().append(createAnimationTriggerValue(animList->animation(i).trigger().get(), style));
1491     } else
1492         list.get().append(createAnimationTriggerValue(Animation::initialTrigger().get(), style));
1493
1494     return list;
1495 }
1496 #endif
1497
1498 static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
1499 {
1500     if (!lineBoxContain)
1501         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1502     return CSSLineBoxContainValue::create(lineBoxContain);
1503 }
1504
1505 ComputedStyleExtractor::ComputedStyleExtractor(PassRefPtr<Node> node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier)
1506     : m_node(node)
1507     , m_pseudoElementSpecifier(pseudoElementSpecifier)
1508     , m_allowVisitedStyle(allowVisitedStyle)
1509 {
1510 }
1511
1512
1513 CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
1514     : m_node(n)
1515     , m_allowVisitedStyle(allowVisitedStyle)
1516     , m_refCount(1)
1517 {
1518     unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
1519     m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType(
1520     (pseudoElementName.substringSharingImpl(nameWithoutColonsStart))));
1521 }
1522
1523 CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
1524 {
1525 }
1526
1527 void CSSComputedStyleDeclaration::ref()
1528 {
1529     ++m_refCount;
1530 }
1531
1532 void CSSComputedStyleDeclaration::deref()
1533 {
1534     ASSERT(m_refCount);
1535     if (!--m_refCount)
1536         delete this;
1537 }
1538
1539 String CSSComputedStyleDeclaration::cssText() const
1540 {
1541     StringBuilder result;
1542
1543     for (unsigned i = 0; i < numComputedProperties; i++) {
1544         if (i)
1545             result.append(' ');
1546         result.append(getPropertyName(computedProperties[i]));
1547         result.appendLiteral(": ");
1548         result.append(getPropertyValue(computedProperties[i]));
1549         result.append(';');
1550     }
1551
1552     return result.toString();
1553 }
1554
1555 void CSSComputedStyleDeclaration::setCssText(const String&, ExceptionCode& ec)
1556 {
1557     ec = NO_MODIFICATION_ALLOWED_ERR;
1558 }
1559
1560 RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::getFontSizeCSSValuePreferringKeyword() const
1561 {
1562     if (!m_node)
1563         return nullptr;
1564
1565     m_node->document().updateLayoutIgnorePendingStylesheets();
1566
1567     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1568     if (!style)
1569         return nullptr;
1570
1571     if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier())
1572         return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier);
1573
1574     return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), *style);
1575 }
1576
1577 bool ComputedStyleExtractor::useFixedFontDefaultSize() const
1578 {
1579     if (!m_node)
1580         return false;
1581
1582     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
1583     if (!style)
1584         return false;
1585
1586     return style->fontDescription().useFixedDefaultSize();
1587 }
1588
1589
1590 static CSSValueID identifierForFamily(const AtomicString& family)
1591 {
1592     if (family == cursiveFamily)
1593         return CSSValueCursive;
1594     if (family == fantasyFamily)
1595         return CSSValueFantasy;
1596     if (family == monospaceFamily)
1597         return CSSValueMonospace;
1598     if (family == pictographFamily)
1599         return CSSValueWebkitPictograph;
1600     if (family == sansSerifFamily)
1601         return CSSValueSansSerif;
1602     if (family == serifFamily)
1603         return CSSValueSerif;
1604     return CSSValueInvalid;
1605 }
1606
1607 static Ref<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
1608 {
1609     if (CSSValueID familyIdentifier = identifierForFamily(family))
1610         return CSSValuePool::singleton().createIdentifierValue(familyIdentifier);
1611     return CSSValuePool::singleton().createFontFamilyValue(family);
1612 }
1613
1614 static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
1615 {
1616     auto& cssValuePool = CSSValuePool::singleton();
1617     // Blink value is ignored.
1618     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1619     if (textDecoration & TextDecorationUnderline)
1620         list->append(cssValuePool.createIdentifierValue(CSSValueUnderline));
1621     if (textDecoration & TextDecorationOverline)
1622         list->append(cssValuePool.createIdentifierValue(CSSValueOverline));
1623     if (textDecoration & TextDecorationLineThrough)
1624         list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough));
1625 #if ENABLE(LETTERPRESS)
1626     if (textDecoration & TextDecorationLetterpress)
1627         list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress));
1628 #endif
1629
1630     if (!list->length())
1631         return cssValuePool.createIdentifierValue(CSSValueNone);
1632     return list.releaseNonNull();
1633 }
1634
1635 static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle)
1636 {
1637     switch (textDecorationStyle) {
1638     case TextDecorationStyleSolid:
1639         return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid);
1640     case TextDecorationStyleDouble:
1641         return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble);
1642     case TextDecorationStyleDotted:
1643         return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted);
1644     case TextDecorationStyleDashed:
1645         return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed);
1646     case TextDecorationStyleWavy:
1647         return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy);
1648     }
1649
1650     ASSERT_NOT_REACHED();
1651     return CSSValuePool::singleton().createExplicitInitialValue();
1652 }
1653
1654 static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(TextDecorationSkip textDecorationSkip)
1655 {
1656     switch (textDecorationSkip) {
1657     case TextDecorationSkipAuto:
1658         return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto);
1659     case TextDecorationSkipNone:
1660         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1661     case TextDecorationSkipInk:
1662         return CSSValuePool::singleton().createIdentifierValue(CSSValueInk);
1663     case TextDecorationSkipObjects:
1664         return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects);
1665     }
1666
1667     ASSERT_NOT_REACHED();
1668     return CSSValuePool::singleton().createExplicitInitialValue();
1669 }
1670
1671 static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(TextEmphasisPosition textEmphasisPosition)
1672 {
1673     ASSERT(!((textEmphasisPosition & TextEmphasisPositionOver) && (textEmphasisPosition & TextEmphasisPositionUnder)));
1674     ASSERT(!((textEmphasisPosition & TextEmphasisPositionLeft) && (textEmphasisPosition & TextEmphasisPositionRight)));
1675     auto& cssValuePool = CSSValuePool::singleton();
1676     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1677     if (textEmphasisPosition & TextEmphasisPositionOver)
1678         list->append(cssValuePool.createIdentifierValue(CSSValueOver));
1679     if (textEmphasisPosition & TextEmphasisPositionUnder)
1680         list->append(cssValuePool.createIdentifierValue(CSSValueUnder));
1681     if (textEmphasisPosition & TextEmphasisPositionLeft)
1682         list->append(cssValuePool.createIdentifierValue(CSSValueLeft));
1683     if (textEmphasisPosition & TextEmphasisPositionRight)
1684         list->append(cssValuePool.createIdentifierValue(CSSValueRight));
1685
1686     if (!list->length())
1687         return cssValuePool.createIdentifierValue(CSSValueNone);
1688     return list.releaseNonNull();
1689 }
1690
1691 static Ref<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
1692 {
1693     // For backwards compatibility, if both values are equal, just return one of them. And
1694     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
1695     auto& cssValuePool = CSSValuePool::singleton();
1696     if (xRepeat == yRepeat)
1697         return cssValuePool.createValue(xRepeat);
1698     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
1699         return cssValuePool.createIdentifierValue(CSSValueRepeatX);
1700     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
1701         return cssValuePool.createIdentifierValue(CSSValueRepeatY);
1702
1703     auto list = CSSValueList::createSpaceSeparated();
1704     list.get().append(cssValuePool.createValue(xRepeat));
1705     list.get().append(cssValuePool.createValue(yRepeat));
1706     return WTF::move(list);
1707 }
1708
1709 static Ref<CSSValue> fillSourceTypeToCSSValue(EMaskSourceType type)
1710 {
1711     switch (type) {
1712     case MaskAlpha:
1713         return CSSValuePool::singleton().createValue(CSSValueAlpha);
1714     default:
1715         ASSERT(type == MaskLuminance);
1716         return CSSValuePool::singleton().createValue(CSSValueLuminance);
1717     }
1718 }
1719
1720 static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style)
1721 {
1722     if (fillSize.type == Contain)
1723         return CSSValuePool::singleton().createIdentifierValue(CSSValueContain);
1724
1725     if (fillSize.type == Cover)
1726         return CSSValuePool::singleton().createIdentifierValue(CSSValueCover);
1727
1728     if (fillSize.size.height().isAuto())
1729         return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
1730
1731     auto list = CSSValueList::createSpaceSeparated();
1732     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
1733     list.get().append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
1734     return WTF::move(list);
1735 }
1736
1737 static Ref<CSSValue> altTextToCSSValue(const RenderStyle* style)
1738 {
1739     return CSSValuePool::singleton().createValue(style->contentAltText(), CSSPrimitiveValue::CSS_STRING);
1740 }
1741     
1742 static Ref<CSSValueList> contentToCSSValue(const RenderStyle* style)
1743 {
1744     auto& cssValuePool = CSSValuePool::singleton();
1745     auto list = CSSValueList::createSpaceSeparated();
1746     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
1747         if (is<CounterContentData>(*contentData))
1748             list.get().append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
1749         else if (is<ImageContentData>(*contentData))
1750             list.get().append(*downcast<ImageContentData>(*contentData).image().cssValue());
1751         else if (is<TextContentData>(*contentData))
1752             list.get().append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING));
1753     }
1754     if (style->hasFlowFrom())
1755         list.get().append(cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING));
1756     return list;
1757 }
1758
1759 static RefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPropertyID propertyID)
1760 {
1761     const CounterDirectiveMap* map = style->counterDirectives();
1762     if (!map)
1763         return nullptr;
1764
1765     auto& cssValuePool = CSSValuePool::singleton();
1766     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
1767     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
1768         list->append(cssValuePool.createValue(it->key, CSSPrimitiveValue::CSS_STRING));
1769         short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
1770         list->append(cssValuePool.createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
1771     }
1772     return list.release();
1773 }
1774
1775 static void logUnimplementedPropertyID(CSSPropertyID propertyID)
1776 {
1777     static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet;
1778     if (!propertyIDSet.get().add(propertyID).isNewEntry)
1779         return;
1780
1781     LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
1782 }
1783
1784 static Ref<CSSValueList> fontFamilyFromStyle(RenderStyle* style)
1785 {
1786     auto list = CSSValueList::createCommaSeparated();
1787     for (unsigned i = 0; i < style->fontCascade().familyCount(); ++i)
1788         list.get().append(valueForFamily(style->fontCascade().familyAt(i)));
1789     return list;
1790 }
1791
1792 static Ref<CSSPrimitiveValue> lineHeightFromStyle(RenderStyle& style)
1793 {
1794     Length length = style.lineHeight();
1795     if (length.isNegative()) // If true, line-height not set; use the font's line spacing.
1796         return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style);
1797     if (length.isPercent()) {
1798         // This is imperfect, because it doesn't include the zoom factor and the real computation
1799         // for how high to be in pixels does include things like minimum font size and the zoom factor.
1800         // On the other hand, since font-size doesn't include the zoom factor, we really can't do
1801         // that here either.
1802         return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().specifiedSize()) / 100, style);
1803     }
1804     return zoomAdjustedPixelValue(floatValueForLength(length, 0), style);
1805 }
1806
1807 static Ref<CSSPrimitiveValue> fontSizeFromStyle(RenderStyle& style)
1808 {
1809     return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style);
1810 }
1811
1812 static Ref<CSSPrimitiveValue> fontStyleFromStyle(RenderStyle* style)
1813 {
1814     if (style->fontDescription().italic())
1815         return CSSValuePool::singleton().createIdentifierValue(CSSValueItalic);
1816     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1817 }
1818
1819 static Ref<CSSPrimitiveValue> fontVariantFromStyle(RenderStyle* style)
1820 {
1821     if (style->fontDescription().smallCaps())
1822         return CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps);
1823     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1824 }
1825
1826 static Ref<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style)
1827 {
1828     switch (style->fontDescription().weight()) {
1829     case FontWeight100:
1830         return CSSValuePool::singleton().createIdentifierValue(CSSValue100);
1831     case FontWeight200:
1832         return CSSValuePool::singleton().createIdentifierValue(CSSValue200);
1833     case FontWeight300:
1834         return CSSValuePool::singleton().createIdentifierValue(CSSValue300);
1835     case FontWeightNormal:
1836         return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1837     case FontWeight500:
1838         return CSSValuePool::singleton().createIdentifierValue(CSSValue500);
1839     case FontWeight600:
1840         return CSSValuePool::singleton().createIdentifierValue(CSSValue600);
1841     case FontWeightBold:
1842         return CSSValuePool::singleton().createIdentifierValue(CSSValueBold);
1843     case FontWeight800:
1844         return CSSValuePool::singleton().createIdentifierValue(CSSValue800);
1845     case FontWeight900:
1846         return CSSValuePool::singleton().createIdentifierValue(CSSValue900);
1847     }
1848     ASSERT_NOT_REACHED();
1849     return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal);
1850 }
1851
1852 static Ref<CSSValue> fontSynthesisFromStyle(RenderStyle& style)
1853 {
1854     if (style.fontDescription().fontSynthesis() == FontSynthesisNone)
1855         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
1856
1857     auto list = CSSValueList::createSpaceSeparated();
1858     if (style.fontDescription().fontSynthesis() & FontSynthesisStyle)
1859         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle));
1860     if (style.fontDescription().fontSynthesis() & FontSynthesisWeight)
1861         list.get().append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight));
1862     return Ref<CSSValue>(list.get());
1863 }
1864
1865 typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const;
1866 typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const;
1867
1868 template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter>
1869 inline RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(RenderStyle& style, RenderObject* renderer)
1870 {
1871     Length unzoomzedLength = (style.*lengthGetter)();
1872     if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed())
1873         return zoomAdjustedPixelValueForLength(unzoomzedLength, style);
1874     return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style);
1875 }
1876
1877 template<RenderStyleLengthGetter lengthGetter>
1878 inline bool paddingOrMarginIsRendererDependent(RenderStyle* style, RenderObject* renderer)
1879 {
1880     if (!renderer || !renderer->isBox())
1881         return false;
1882     return !(style && (style->*lengthGetter)().isFixed());
1883 }
1884
1885 static bool isLayoutDependent(CSSPropertyID propertyID, RenderStyle* style, RenderObject* renderer)
1886 {
1887     switch (propertyID) {
1888     case CSSPropertyWidth:
1889     case CSSPropertyHeight:
1890     case CSSPropertyPerspectiveOrigin:
1891     case CSSPropertyTransformOrigin:
1892     case CSSPropertyTransform:
1893     case CSSPropertyFilter:
1894 #if ENABLE(FILTERS_LEVEL_2)
1895     case CSSPropertyWebkitBackdropFilter:
1896 #endif
1897         return true;
1898     case CSSPropertyMargin: {
1899         if (!renderer || !renderer->isBox())
1900             return false;
1901         return !(style && style->marginTop().isFixed() && style->marginRight().isFixed()
1902             && style->marginBottom().isFixed() && style->marginLeft().isFixed());
1903     }
1904     case CSSPropertyMarginTop:
1905         return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer);
1906     case CSSPropertyMarginRight:
1907         return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer);
1908     case CSSPropertyMarginBottom:
1909         return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer);
1910     case CSSPropertyMarginLeft:
1911         return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer);
1912     case CSSPropertyPadding: {
1913         if (!renderer || !renderer->isBox())
1914             return false;
1915         return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed()
1916             && style->paddingBottom().isFixed() && style->paddingLeft().isFixed());
1917     }
1918     case CSSPropertyPaddingTop:
1919         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer);
1920     case CSSPropertyPaddingRight:
1921         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer);
1922     case CSSPropertyPaddingBottom:
1923         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer);
1924     case CSSPropertyPaddingLeft:
1925         return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); 
1926 #if ENABLE(CSS_GRID_LAYOUT)
1927     case CSSPropertyWebkitGridTemplateColumns:
1928     case CSSPropertyWebkitGridTemplateRows:
1929     case CSSPropertyWebkitGridTemplate:
1930     case CSSPropertyWebkitGrid:
1931         return renderer && renderer->isRenderGrid();
1932 #endif
1933     default:
1934         return false;
1935     }
1936 }
1937
1938 Node* ComputedStyleExtractor::styledNode() const
1939 {
1940     if (!m_node)
1941         return nullptr;
1942     if (!is<Element>(*m_node))
1943         return m_node.get();
1944     Element& element = downcast<Element>(*m_node);
1945     PseudoElement* pseudoElement;
1946     if (m_pseudoElementSpecifier == BEFORE && (pseudoElement = element.beforePseudoElement()))
1947         return pseudoElement;
1948     if (m_pseudoElementSpecifier == AFTER && (pseudoElement = element.afterPseudoElement()))
1949         return pseudoElement;
1950     return &element;
1951 }
1952
1953 static ItemPosition resolveContainerAlignmentAuto(ItemPosition position, RenderObject* element)
1954 {
1955     if (position != ItemPositionAuto || !element)
1956         return position;
1957
1958     return element->style().isDisplayFlexibleOrGridBox() ? ItemPositionStretch : ItemPositionStart;
1959 }
1960
1961 static ItemPosition resolveSelfAlignmentAuto(ItemPosition position, OverflowAlignment& overflow, RenderObject* element)
1962 {
1963     if (position != ItemPositionAuto || !element || element->isOutOfFlowPositioned())
1964         return position;
1965
1966     RenderBlock* parent = element->containingBlock();
1967     if (!parent)
1968         return ItemPositionStart;
1969
1970     overflow = parent->style().alignItemsOverflowAlignment();
1971     return resolveContainerAlignmentAuto(parent->style().alignItemsPosition(), parent);
1972 }
1973
1974 static void resolveContentAlignmentAuto(ContentPosition& position, ContentDistributionType& distribution, RenderObject* element)
1975 {
1976     if (position != ContentPositionAuto || distribution != ContentDistributionDefault || !element)
1977         return;
1978
1979     // Even that both align-content and justify-content 'auto' values are resolved to 'stretch'
1980     // in case of flexbox containers, 'stretch' value in justify-content will behave like 'flex-start'. 
1981     if (element->style().isDisplayFlexibleBox())
1982         distribution = ContentDistributionStretch;
1983     else
1984         position = ContentPositionStart;
1985 }
1986
1987 RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
1988 {
1989     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout);
1990 }
1991
1992 Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const
1993 {
1994     return ComputedStyleExtractor(m_node, m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties();
1995 }
1996
1997 static inline bool nodeOrItsAncestorNeedsStyleRecalc(const Node& node)
1998 {
1999     if (node.needsStyleRecalc())
2000         return true;
2001
2002     const Node* currentNode = &node;
2003     const Element* ancestor = currentNode->parentOrShadowHostElement();
2004     while (ancestor) {
2005         if (ancestor->needsStyleRecalc())
2006             return true;
2007
2008         if (ancestor->directChildNeedsStyleRecalc() && currentNode->styleIsAffectedByPreviousSibling())
2009             return true;
2010
2011         currentNode = ancestor;
2012         ancestor = currentNode->parentOrShadowHostElement();
2013     }
2014     return false;
2015 }
2016
2017 static inline bool updateStyleIfNeededForNode(const Node& node)
2018 {
2019     Document& document = node.document();
2020     if (!document.hasPendingForcedStyleRecalc() && !(document.childNeedsStyleRecalc() && nodeOrItsAncestorNeedsStyleRecalc(node)))
2021         return false;
2022     document.updateStyleIfNeeded();
2023     return true;
2024 }
2025
2026 static inline RefPtr<RenderStyle> computeRenderStyleForProperty(Node* styledNode, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID)
2027 {
2028     RenderObject* renderer = styledNode->renderer();
2029
2030     if (renderer && renderer->isComposited() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
2031         RefPtr<RenderStyle> style = renderer->animation().getAnimatedStyleForRenderer(downcast<RenderElement>(*renderer));
2032         if (pseudoElementSpecifier && !styledNode->isPseudoElement()) {
2033             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
2034             return style->getCachedPseudoStyle(pseudoElementSpecifier);
2035         }
2036         return style;
2037     }
2038
2039     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
2040 }
2041
2042 #if ENABLE(CSS_SHAPES)
2043 static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue)
2044 {
2045     if (!shapeValue)
2046         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2047
2048     if (shapeValue->type() == ShapeValue::Type::Box)
2049         return CSSValuePool::singleton().createValue(shapeValue->cssBox());
2050
2051     if (shapeValue->type() == ShapeValue::Type::Image) {
2052         if (shapeValue->image())
2053             return *shapeValue->image()->cssValue();
2054         return CSSValuePool::singleton().createIdentifierValue(CSSValueNone);
2055     }
2056
2057     ASSERT(shapeValue->type() == ShapeValue::Type::Shape);
2058
2059     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2060     list->append(valueForBasicShape(style, *shapeValue->shape()));
2061     if (shapeValue->cssBox() != BoxMissing)
2062         list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox()));
2063     return list.releaseNonNull();
2064 }
2065 #endif
2066
2067 static RefPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment, ItemPositionType positionType)
2068 {
2069     auto& cssValuePool = CSSValuePool::singleton();
2070     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2071     if (positionType == LegacyPosition)
2072         result->append(CSSPrimitiveValue::createIdentifier(CSSValueLegacy));
2073     result->append(cssValuePool.createValue(itemPosition));
2074     if (overflowAlignment != OverflowAlignmentDefault)
2075         result->append(cssValuePool.createValue(overflowAlignment));
2076     ASSERT(result->length() <= 2);
2077     return result;
2078 }
2079
2080 static RefPtr<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(ContentPosition position, ContentDistributionType distribution, OverflowAlignment overflowAlignment)
2081 {
2082     RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
2083     if (distribution != ContentDistributionDefault)
2084         result->append(CSSPrimitiveValue::create(distribution));
2085     if (distribution == ContentDistributionDefault || position != ContentPositionAuto)
2086         result->append(CSSPrimitiveValue::create(position));
2087     if ((position >= ContentPositionCenter || distribution != ContentDistributionDefault) && overflowAlignment != OverflowAlignmentDefault)
2088         result->append(CSSPrimitiveValue::create(overflowAlignment));
2089     ASSERT(result->length() > 0);
2090     ASSERT(result->length() <= 3);
2091     return result;
2092 }
2093
2094 inline static bool isFlexOrGrid(ContainerNode* element)
2095 {
2096     return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox();
2097 }
2098
2099 RefPtr<CSSValue> ComputedStyleExtractor::customPropertyValue(const String& propertyName) const
2100 {
2101     Node* styledNode = this->styledNode();
2102     if (!styledNode)
2103         return nullptr;
2104
2105     RefPtr<RenderStyle> style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, CSSPropertyCustom);
2106     if (!style || !style->hasCustomProperty(propertyName))
2107         return nullptr;
2108
2109     return style->getCustomPropertyValue(propertyName);
2110 }
2111
2112 String ComputedStyleExtractor::customPropertyText(const String& propertyName) const
2113 {
2114     RefPtr<CSSValue> propertyValue = this->customPropertyValue(propertyName);
2115     return propertyValue ? propertyValue->cssText() : emptyString();
2116 }
2117
2118 RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
2119 {
2120     Node* styledNode = this->styledNode();
2121     if (!styledNode)
2122         return nullptr;
2123
2124     RefPtr<RenderStyle> style;
2125     RenderObject* renderer = nullptr;
2126     bool forceFullLayout = false;
2127     if (updateLayout) {
2128         Document& document = styledNode->document();
2129
2130         if (updateStyleIfNeededForNode(*styledNode)) {
2131             // The style recalc could have caused the styled node to be discarded or replaced
2132             // if it was a PseudoElement so we need to update it.
2133             styledNode = this->styledNode();
2134         }
2135
2136         renderer = styledNode->renderer();
2137
2138         if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledNode) && !downcast<SVGElement>(*styledNode).isValid())
2139             return nullptr;
2140
2141         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
2142
2143         // FIXME: Some of these cases could be narrowed down or optimized better.
2144         forceFullLayout = isLayoutDependent(propertyID, style.get(), renderer)
2145             || styledNode->isInShadowTree()
2146             || (document.styleResolverIfExists() && document.styleResolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement());
2147
2148         if (forceFullLayout) {
2149             document.updateLayoutIgnorePendingStylesheets();
2150             styledNode = this->styledNode();
2151         }
2152     }
2153
2154     if (!updateLayout || forceFullLayout) {
2155         style = computeRenderStyleForProperty(styledNode, m_pseudoElementSpecifier, propertyID);
2156         renderer = styledNode->renderer();
2157     }
2158
2159     if (!style)
2160         return nullptr;
2161
2162     auto& cssValuePool = CSSValuePool::singleton();
2163     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
2164
2165     switch (propertyID) {
2166         case CSSPropertyInvalid:
2167             break;
2168
2169         case CSSPropertyBackgroundColor:
2170             return cssValuePool.createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
2171         case CSSPropertyBackgroundImage:
2172         case CSSPropertyWebkitMaskImage: {
2173             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
2174             if (!layers)
2175                 return cssValuePool.createIdentifierValue(CSSValueNone);
2176
2177             if (!layers->next()) {
2178                 if (layers->image())
2179                     return layers->image()->cssValue();
2180
2181                 return cssValuePool.createIdentifierValue(CSSValueNone);
2182             }
2183
2184             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2185             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2186                 if (currLayer->image())
2187                     list->append(*currLayer->image()->cssValue());
2188                 else
2189                     list->append(cssValuePool.createIdentifierValue(CSSValueNone));
2190             }
2191             return list;
2192         }
2193         case CSSPropertyBackgroundSize:
2194         case CSSPropertyWebkitBackgroundSize:
2195         case CSSPropertyWebkitMaskSize: {
2196             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
2197             if (!layers->next())
2198                 return fillSizeToCSSValue(layers->size(), *style);
2199
2200             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2201             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2202                 list->append(fillSizeToCSSValue(currLayer->size(), *style));
2203
2204             return list;
2205         }
2206         case CSSPropertyBackgroundRepeat:
2207         case CSSPropertyWebkitMaskRepeat: {
2208             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
2209             if (!layers->next())
2210                 return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
2211
2212             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2213             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2214                 list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
2215
2216             return list;
2217         }
2218         case CSSPropertyWebkitMaskSourceType: {
2219             const FillLayer* layers = style->maskLayers();
2220
2221             if (!layers)
2222                 return cssValuePool.createIdentifierValue(CSSValueNone);
2223
2224             if (!layers->next())
2225                 return fillSourceTypeToCSSValue(layers->maskSourceType());
2226
2227             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2228             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2229                 list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType()));
2230
2231             return list;
2232         }
2233         case CSSPropertyWebkitBackgroundComposite:
2234         case CSSPropertyWebkitMaskComposite: {
2235             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
2236             if (!layers->next())
2237                 return cssValuePool.createValue(layers->composite());
2238
2239             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2240             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2241                 list->append(cssValuePool.createValue(currLayer->composite()));
2242
2243             return list;
2244         }
2245         case CSSPropertyBackgroundAttachment: {
2246             const FillLayer* layers = style->backgroundLayers();
2247             if (!layers->next())
2248                 return cssValuePool.createValue(layers->attachment());
2249
2250             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2251             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2252                 list->append(cssValuePool.createValue(currLayer->attachment()));
2253
2254             return list;
2255         }
2256         case CSSPropertyBackgroundClip:
2257         case CSSPropertyBackgroundOrigin:
2258         case CSSPropertyWebkitBackgroundClip:
2259         case CSSPropertyWebkitBackgroundOrigin:
2260         case CSSPropertyWebkitMaskClip:
2261         case CSSPropertyWebkitMaskOrigin: {
2262             const FillLayer* layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style->maskLayers() : style->backgroundLayers();
2263             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
2264             if (!layers->next()) {
2265                 EFillBox box = isClip ? layers->clip() : layers->origin();
2266                 return cssValuePool.createValue(box);
2267             }
2268
2269             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2270             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
2271                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
2272                 list->append(cssValuePool.createValue(box));
2273             }
2274
2275             return list;
2276         }
2277         case CSSPropertyBackgroundPosition:
2278         case CSSPropertyWebkitMaskPosition: {
2279             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
2280             if (!layers->next())
2281                 return createPositionListForLayer(propertyID, layers, *style);
2282
2283             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2284             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2285                 list->append(createPositionListForLayer(propertyID, currLayer, *style));
2286             return list;
2287         }
2288         case CSSPropertyBackgroundPositionX:
2289         case CSSPropertyWebkitMaskPositionX: {
2290             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
2291             if (!layers->next())
2292                 return cssValuePool.createValue(layers->xPosition());
2293
2294             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2295             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2296                 list->append(cssValuePool.createValue(currLayer->xPosition()));
2297
2298             return list;
2299         }
2300         case CSSPropertyBackgroundPositionY:
2301         case CSSPropertyWebkitMaskPositionY: {
2302             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
2303             if (!layers->next())
2304                 return cssValuePool.createValue(layers->yPosition());
2305
2306             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2307             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
2308                 list->append(cssValuePool.createValue(currLayer->yPosition()));
2309
2310             return list;
2311         }
2312         case CSSPropertyBorderCollapse:
2313             if (style->borderCollapse())
2314                 return cssValuePool.createIdentifierValue(CSSValueCollapse);
2315             return cssValuePool.createIdentifierValue(CSSValueSeparate);
2316         case CSSPropertyBorderSpacing: {
2317             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2318             list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
2319             list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
2320             return list;
2321         }
2322         case CSSPropertyWebkitBorderHorizontalSpacing:
2323             return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style);
2324         case CSSPropertyWebkitBorderVerticalSpacing:
2325             return zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style);
2326         case CSSPropertyBorderImageSource:
2327             if (style->borderImageSource())
2328                 return style->borderImageSource()->cssValue();
2329             return cssValuePool.createIdentifierValue(CSSValueNone);
2330         case CSSPropertyBorderTopColor:
2331             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
2332         case CSSPropertyBorderRightColor:
2333             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
2334         case CSSPropertyBorderBottomColor:
2335             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
2336         case CSSPropertyBorderLeftColor:
2337             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
2338         case CSSPropertyBorderTopStyle:
2339             return cssValuePool.createValue(style->borderTopStyle());
2340         case CSSPropertyBorderRightStyle:
2341             return cssValuePool.createValue(style->borderRightStyle());
2342         case CSSPropertyBorderBottomStyle:
2343             return cssValuePool.createValue(style->borderBottomStyle());
2344         case CSSPropertyBorderLeftStyle:
2345             return cssValuePool.createValue(style->borderLeftStyle());
2346         case CSSPropertyBorderTopWidth:
2347             return zoomAdjustedPixelValue(style->borderTopWidth(), *style);
2348         case CSSPropertyBorderRightWidth:
2349             return zoomAdjustedPixelValue(style->borderRightWidth(), *style);
2350         case CSSPropertyBorderBottomWidth:
2351             return zoomAdjustedPixelValue(style->borderBottomWidth(), *style);
2352         case CSSPropertyBorderLeftWidth:
2353             return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
2354         case CSSPropertyBottom:
2355             return positionOffsetValue(*style, CSSPropertyBottom);
2356         case CSSPropertyWebkitBoxAlign:
2357             return cssValuePool.createValue(style->boxAlign());
2358 #if ENABLE(CSS_BOX_DECORATION_BREAK)
2359         case CSSPropertyWebkitBoxDecorationBreak:
2360             if (style->boxDecorationBreak() == DSLICE)
2361                 return cssValuePool.createIdentifierValue(CSSValueSlice);
2362         return cssValuePool.createIdentifierValue(CSSValueClone);
2363 #endif
2364         case CSSPropertyWebkitBoxDirection:
2365             return cssValuePool.createValue(style->boxDirection());
2366         case CSSPropertyWebkitBoxFlex:
2367             return cssValuePool.createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
2368         case CSSPropertyWebkitBoxFlexGroup:
2369             return cssValuePool.createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
2370         case CSSPropertyWebkitBoxLines:
2371             return cssValuePool.createValue(style->boxLines());
2372         case CSSPropertyWebkitBoxOrdinalGroup:
2373             return cssValuePool.createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
2374         case CSSPropertyWebkitBoxOrient:
2375             return cssValuePool.createValue(style->boxOrient());
2376         case CSSPropertyWebkitBoxPack:
2377             return cssValuePool.createValue(style->boxPack());
2378         case CSSPropertyWebkitBoxReflect:
2379             return valueForReflection(style->boxReflect(), *style);
2380         case CSSPropertyBoxShadow:
2381         case CSSPropertyWebkitBoxShadow:
2382             return valueForShadow(style->boxShadow(), propertyID, *style);
2383         case CSSPropertyCaptionSide:
2384             return cssValuePool.createValue(style->captionSide());
2385         case CSSPropertyClear:
2386             return cssValuePool.createValue(style->clear());
2387         case CSSPropertyColor:
2388             return cssValuePool.createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
2389         case CSSPropertyWebkitPrintColorAdjust:
2390             return cssValuePool.createValue(style->printColorAdjust());
2391         case CSSPropertyWebkitColumnAxis:
2392             return cssValuePool.createValue(style->columnAxis());
2393         case CSSPropertyColumnCount:
2394             if (style->hasAutoColumnCount())
2395                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2396             return cssValuePool.createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
2397         case CSSPropertyColumnFill:
2398             return cssValuePool.createValue(style->columnFill());
2399         case CSSPropertyColumnGap:
2400             if (style->hasNormalColumnGap())
2401                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2402             return zoomAdjustedPixelValue(style->columnGap(), *style);
2403         case CSSPropertyColumnProgression:
2404             return cssValuePool.createValue(style->columnProgression());
2405         case CSSPropertyColumnRuleColor:
2406             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
2407         case CSSPropertyColumnRuleStyle:
2408             return cssValuePool.createValue(style->columnRuleStyle());
2409         case CSSPropertyColumnRuleWidth:
2410             return zoomAdjustedPixelValue(style->columnRuleWidth(), *style);
2411         case CSSPropertyColumnSpan:
2412             return cssValuePool.createIdentifierValue(style->columnSpan() ? CSSValueAll : CSSValueNone);
2413         case CSSPropertyWebkitColumnBreakAfter:
2414             return cssValuePool.createValue(style->columnBreakAfter());
2415         case CSSPropertyWebkitColumnBreakBefore:
2416             return cssValuePool.createValue(style->columnBreakBefore());
2417         case CSSPropertyWebkitColumnBreakInside:
2418             return cssValuePool.createValue(style->columnBreakInside());
2419         case CSSPropertyColumnWidth:
2420             if (style->hasAutoColumnWidth())
2421                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2422             return zoomAdjustedPixelValue(style->columnWidth(), *style);
2423         case CSSPropertyTabSize:
2424             return cssValuePool.createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
2425 #if ENABLE(CSS_REGIONS)
2426         case CSSPropertyWebkitRegionBreakAfter:
2427             return cssValuePool.createValue(style->regionBreakAfter());
2428         case CSSPropertyWebkitRegionBreakBefore:
2429             return cssValuePool.createValue(style->regionBreakBefore());
2430         case CSSPropertyWebkitRegionBreakInside:
2431             return cssValuePool.createValue(style->regionBreakInside());
2432 #endif
2433         case CSSPropertyCursor: {
2434             RefPtr<CSSValueList> list;
2435             CursorList* cursors = style->cursors();
2436             if (cursors && cursors->size() > 0) {
2437                 list = CSSValueList::createCommaSeparated();
2438                 for (unsigned i = 0; i < cursors->size(); ++i)
2439                     if (StyleImage* image = cursors->at(i).image())
2440                         list->append(*image->cssValue());
2441             }
2442             auto value = cssValuePool.createValue(style->cursor());
2443             if (list) {
2444                 list->append(WTF::move(value));
2445                 return list;
2446             }
2447             return WTF::move(value);
2448         }
2449 #if ENABLE(CURSOR_VISIBILITY)
2450         case CSSPropertyWebkitCursorVisibility:
2451             return cssValuePool.createValue(style->cursorVisibility());
2452 #endif
2453         case CSSPropertyDirection:
2454             return cssValuePool.createValue(style->direction());
2455         case CSSPropertyDisplay:
2456             return cssValuePool.createValue(style->display());
2457         case CSSPropertyEmptyCells:
2458             return cssValuePool.createValue(style->emptyCells());
2459         case CSSPropertyAlignContent: {
2460             ContentPosition position = style->alignContentPosition();
2461             ContentDistributionType distribution = style->alignContentDistribution();
2462             resolveContentAlignmentAuto(position, distribution, renderer);
2463             return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->alignContentOverflowAlignment());
2464         }
2465         case CSSPropertyAlignItems:
2466             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->alignItemsPosition(), renderer), style->alignItemsOverflowAlignment(), NonLegacyPosition);
2467         case CSSPropertyAlignSelf: {
2468             OverflowAlignment overflow = style->alignSelfOverflowAlignment();
2469             ItemPosition alignSelf = resolveSelfAlignmentAuto(style->alignSelfPosition(), overflow, renderer);
2470             return valueForItemPositionWithOverflowAlignment(alignSelf, overflow, NonLegacyPosition);
2471         }
2472         case CSSPropertyFlex:
2473             return getCSSPropertyValuesForShorthandProperties(flexShorthand());
2474         case CSSPropertyFlexBasis:
2475             return cssValuePool.createValue(style->flexBasis());
2476         case CSSPropertyFlexDirection:
2477             return cssValuePool.createValue(style->flexDirection());
2478         case CSSPropertyFlexFlow:
2479             return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand());
2480         case CSSPropertyFlexGrow:
2481             return cssValuePool.createValue(style->flexGrow());
2482         case CSSPropertyFlexShrink:
2483             return cssValuePool.createValue(style->flexShrink());
2484         case CSSPropertyFlexWrap:
2485             return cssValuePool.createValue(style->flexWrap());
2486         case CSSPropertyJustifyContent: {
2487             ContentPosition position = style->justifyContentPosition();
2488             ContentDistributionType distribution = style->justifyContentDistribution();
2489             resolveContentAlignmentAuto(position, distribution, renderer);
2490             return valueForContentPositionAndDistributionWithOverflowAlignment(position, distribution, style->justifyContentOverflowAlignment());
2491         }
2492         case CSSPropertyJustifyItems:
2493             return valueForItemPositionWithOverflowAlignment(resolveContainerAlignmentAuto(style->justifyItemsPosition(), renderer), style->justifyItemsOverflowAlignment(), style->justifyItemsPositionType());
2494         case CSSPropertyJustifySelf: {
2495             OverflowAlignment overflow = style->justifySelfOverflowAlignment();
2496             ItemPosition justifySelf = resolveSelfAlignmentAuto(style->justifySelfPosition(), overflow, renderer);
2497             return valueForItemPositionWithOverflowAlignment(justifySelf, overflow, NonLegacyPosition);
2498         }
2499         case CSSPropertyOrder:
2500             return cssValuePool.createValue(style->order(), CSSPrimitiveValue::CSS_NUMBER);
2501         case CSSPropertyFloat:
2502             if (style->display() != NONE && style->hasOutOfFlowPosition())
2503                 return cssValuePool.createIdentifierValue(CSSValueNone);
2504             return cssValuePool.createValue(style->floating());
2505         case CSSPropertyFont: {
2506             RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
2507             computedFont->style = fontStyleFromStyle(style.get());
2508             computedFont->variant = fontVariantFromStyle(style.get());
2509             computedFont->weight = fontWeightFromStyle(style.get());
2510             computedFont->size = fontSizeFromStyle(*style);
2511             computedFont->lineHeight = lineHeightFromStyle(*style);
2512             computedFont->family = fontFamilyFromStyle(style.get());
2513             return computedFont;
2514         }
2515         case CSSPropertyFontFamily: {
2516             RefPtr<CSSValueList> fontFamilyList = fontFamilyFromStyle(style.get());
2517             // If there's only a single family, return that as a CSSPrimitiveValue.
2518             // NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
2519             if (fontFamilyList->length() == 1)
2520                 return fontFamilyList->item(0);
2521             return fontFamilyList;
2522         }
2523         case CSSPropertyFontSize:
2524             return fontSizeFromStyle(*style);
2525         case CSSPropertyFontStyle:
2526             return fontStyleFromStyle(style.get());
2527         case CSSPropertyFontVariant:
2528             return fontVariantFromStyle(style.get());
2529         case CSSPropertyFontWeight:
2530             return fontWeightFromStyle(style.get());
2531         case CSSPropertyFontSynthesis:
2532             return fontSynthesisFromStyle(*style);
2533         case CSSPropertyWebkitFontFeatureSettings: {
2534             const FontFeatureSettings& featureSettings = style->fontDescription().featureSettings();
2535             if (!featureSettings.size())
2536                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2537             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2538             for (auto& feature : featureSettings)
2539                 list->append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
2540             return list;
2541         }
2542 #if ENABLE(CSS_GRID_LAYOUT)
2543         case CSSPropertyWebkitGridAutoFlow: {
2544             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2545             ASSERT(style->isGridAutoFlowDirectionRow() || style->isGridAutoFlowDirectionColumn());
2546             if (style->isGridAutoFlowDirectionRow())
2547                 list->append(cssValuePool.createIdentifierValue(CSSValueRow));
2548             else
2549                 list->append(cssValuePool.createIdentifierValue(CSSValueColumn));
2550
2551             if (style->isGridAutoFlowAlgorithmDense())
2552                 list->append(cssValuePool.createIdentifierValue(CSSValueDense));
2553
2554             return list;
2555         }
2556
2557         // Specs mention that getComputedStyle() should return the used value of the property instead of the computed
2558         // one for grid-definition-{rows|columns} but not for the grid-auto-{rows|columns} as things like
2559         // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things
2560         // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
2561         // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
2562         case CSSPropertyWebkitGridAutoColumns:
2563             return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
2564         case CSSPropertyWebkitGridAutoRows:
2565             return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
2566
2567         case CSSPropertyWebkitGridTemplateColumns:
2568             return valueForGridTrackList(ForColumns, renderer, *style);
2569         case CSSPropertyWebkitGridTemplateRows:
2570             return valueForGridTrackList(ForRows, renderer, *style);
2571
2572         case CSSPropertyWebkitGridColumnStart:
2573             return valueForGridPosition(style->gridItemColumnStart());
2574         case CSSPropertyWebkitGridColumnEnd:
2575             return valueForGridPosition(style->gridItemColumnEnd());
2576         case CSSPropertyWebkitGridRowStart:
2577             return valueForGridPosition(style->gridItemRowStart());
2578         case CSSPropertyWebkitGridRowEnd:
2579             return valueForGridPosition(style->gridItemRowEnd());
2580         case CSSPropertyWebkitGridArea:
2581             return getCSSPropertyValuesForGridShorthand(webkitGridAreaShorthand());
2582         case CSSPropertyWebkitGridTemplate:
2583             return getCSSPropertyValuesForGridShorthand(webkitGridTemplateShorthand());
2584         case CSSPropertyWebkitGrid:
2585             return getCSSPropertyValuesForGridShorthand(webkitGridShorthand());
2586         case CSSPropertyWebkitGridColumn:
2587             return getCSSPropertyValuesForGridShorthand(webkitGridColumnShorthand());
2588         case CSSPropertyWebkitGridRow:
2589             return getCSSPropertyValuesForGridShorthand(webkitGridRowShorthand());
2590
2591         case CSSPropertyWebkitGridTemplateAreas:
2592             if (!style->namedGridAreaRowCount()) {
2593                 ASSERT(!style->namedGridAreaColumnCount());
2594                 return cssValuePool.createIdentifierValue(CSSValueNone);
2595             }
2596
2597             return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
2598 #endif /* ENABLE(CSS_GRID_LAYOUT) */
2599         case CSSPropertyHeight:
2600             if (renderer && !renderer->isRenderSVGModelObject()) {
2601                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property,
2602                 // the "height" property does not apply for non-replaced inline elements.
2603                 if (!renderer->isReplaced() && renderer->isInline())
2604                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2605                 return zoomAdjustedPixelValue(sizingBox(*renderer).height(), *style);
2606             }
2607             return zoomAdjustedPixelValueForLength(style->height(), *style);
2608         case CSSPropertyWebkitHyphens:
2609             return cssValuePool.createValue(style->hyphens());
2610         case CSSPropertyWebkitHyphenateCharacter:
2611             if (style->hyphenationString().isNull())
2612                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2613             return cssValuePool.createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
2614         case CSSPropertyWebkitHyphenateLimitAfter:
2615             if (style->hyphenationLimitAfter() < 0)
2616                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2617             return CSSPrimitiveValue::create(style->hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER);
2618         case CSSPropertyWebkitHyphenateLimitBefore:
2619             if (style->hyphenationLimitBefore() < 0)
2620                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
2621             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
2622         case CSSPropertyWebkitHyphenateLimitLines:
2623             if (style->hyphenationLimitLines() < 0)
2624                 return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit);
2625             return CSSPrimitiveValue::create(style->hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER);
2626         case CSSPropertyWebkitBorderFit:
2627             if (style->borderFit() == BorderFitBorder)
2628                 return cssValuePool.createIdentifierValue(CSSValueBorder);
2629             return cssValuePool.createIdentifierValue(CSSValueLines);
2630 #if ENABLE(CSS_IMAGE_ORIENTATION)
2631         case CSSPropertyImageOrientation:
2632             return cssValuePool.createValue(style->imageOrientation());
2633 #endif
2634         case CSSPropertyImageRendering:
2635             return CSSPrimitiveValue::create(style->imageRendering());
2636 #if ENABLE(CSS_IMAGE_RESOLUTION)
2637         case CSSPropertyImageResolution:
2638             return cssValuePool.createValue(style->imageResolution(), CSSPrimitiveValue::CSS_DPPX);
2639 #endif
2640         case CSSPropertyLeft:
2641             return positionOffsetValue(*style, CSSPropertyLeft);
2642         case CSSPropertyLetterSpacing:
2643             if (!style->letterSpacing())
2644                 return cssValuePool.createIdentifierValue(CSSValueNormal);
2645             return zoomAdjustedPixelValue(style->letterSpacing(), *style);
2646         case CSSPropertyWebkitLineClamp:
2647             if (style->lineClamp().isNone())
2648                 return cssValuePool.createIdentifierValue(CSSValueNone);
2649             return cssValuePool.createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
2650         case CSSPropertyLineHeight:
2651             return lineHeightFromStyle(*style);
2652         case CSSPropertyListStyleImage:
2653             if (style->listStyleImage())
2654                 return style->listStyleImage()->cssValue();
2655             return cssValuePool.createIdentifierValue(CSSValueNone);
2656         case CSSPropertyListStylePosition:
2657             return cssValuePool.createValue(style->listStylePosition());
2658         case CSSPropertyListStyleType:
2659             return cssValuePool.createValue(style->listStyleType());
2660         case CSSPropertyWebkitLocale:
2661             if (style->locale().isNull())
2662                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2663             return cssValuePool.createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
2664         case CSSPropertyMarginTop:
2665             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(*style, renderer);
2666         case CSSPropertyMarginRight: {
2667             Length marginRight = style->marginRight();
2668             if (marginRight.isFixed() || !is<RenderBox>(renderer))
2669                 return zoomAdjustedPixelValueForLength(marginRight, *style);
2670             float value;
2671             if (marginRight.isPercentOrCalculated()) {
2672                 // RenderBox gives a marginRight() that is the distance between the right-edge of the child box
2673                 // and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
2674                 // value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
2675                 value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent());
2676             } else
2677                 value = downcast<RenderBox>(*renderer).marginRight();
2678             return zoomAdjustedPixelValue(value, *style);
2679         }
2680         case CSSPropertyMarginBottom:
2681             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(*style, renderer);
2682         case CSSPropertyMarginLeft:
2683             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(*style, renderer);
2684         case CSSPropertyWebkitMarqueeDirection:
2685             return cssValuePool.createValue(style->marqueeDirection());
2686         case CSSPropertyWebkitMarqueeIncrement:
2687             return cssValuePool.createValue(style->marqueeIncrement());
2688         case CSSPropertyWebkitMarqueeRepetition:
2689             if (style->marqueeLoopCount() < 0)
2690                 return cssValuePool.createIdentifierValue(CSSValueInfinite);
2691             return cssValuePool.createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
2692         case CSSPropertyWebkitMarqueeStyle:
2693             return cssValuePool.createValue(style->marqueeBehavior());
2694         case CSSPropertyWebkitUserModify:
2695             return cssValuePool.createValue(style->userModify());
2696         case CSSPropertyMaxHeight: {
2697             const Length& maxHeight = style->maxHeight();
2698             if (maxHeight.isUndefined())
2699                 return cssValuePool.createIdentifierValue(CSSValueNone);
2700             return zoomAdjustedPixelValueForLength(maxHeight, *style);
2701         }
2702         case CSSPropertyMaxWidth: {
2703             const Length& maxWidth = style->maxWidth();
2704             if (maxWidth.isUndefined())
2705                 return cssValuePool.createIdentifierValue(CSSValueNone);
2706             return zoomAdjustedPixelValueForLength(maxWidth, *style);
2707         }
2708         case CSSPropertyMinHeight:
2709             if (style->minHeight().isAuto()) {
2710                 if (isFlexOrGrid(styledNode->parentNode()))
2711                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2712                 return zoomAdjustedPixelValue(0, *style);
2713             }
2714             return zoomAdjustedPixelValueForLength(style->minHeight(), *style);
2715         case CSSPropertyMinWidth:
2716             if (style->minWidth().isAuto()) {
2717                 if (isFlexOrGrid(styledNode->parentNode()))
2718                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2719                 return zoomAdjustedPixelValue(0, *style);
2720             }
2721             return zoomAdjustedPixelValueForLength(style->minWidth(), *style);
2722         case CSSPropertyObjectFit:
2723             return cssValuePool.createValue(style->objectFit());
2724         case CSSPropertyOpacity:
2725             return cssValuePool.createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
2726         case CSSPropertyOrphans:
2727             if (style->hasAutoOrphans())
2728                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2729             return cssValuePool.createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
2730         case CSSPropertyOutlineColor:
2731             return m_allowVisitedStyle ? cssValuePool.createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
2732         case CSSPropertyOutlineOffset:
2733             return zoomAdjustedPixelValue(style->outlineOffset(), *style);
2734         case CSSPropertyOutlineStyle:
2735             if (style->outlineStyleIsAuto())
2736                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2737             return cssValuePool.createValue(style->outlineStyle());
2738         case CSSPropertyOutlineWidth:
2739             return zoomAdjustedPixelValue(style->outlineWidth(), *style);
2740         case CSSPropertyOverflow:
2741             return cssValuePool.createValue(std::max(style->overflowX(), style->overflowY()));
2742         case CSSPropertyOverflowWrap:
2743             return cssValuePool.createValue(style->overflowWrap());
2744         case CSSPropertyOverflowX:
2745             return cssValuePool.createValue(style->overflowX());
2746         case CSSPropertyOverflowY:
2747             return cssValuePool.createValue(style->overflowY());
2748         case CSSPropertyPaddingTop:
2749             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(*style, renderer);
2750         case CSSPropertyPaddingRight:
2751             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(*style, renderer);
2752         case CSSPropertyPaddingBottom:
2753             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(*style, renderer);
2754         case CSSPropertyPaddingLeft:
2755             return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(*style, renderer);
2756         case CSSPropertyPageBreakAfter:
2757             return cssValuePool.createValue(style->pageBreakAfter());
2758         case CSSPropertyPageBreakBefore:
2759             return cssValuePool.createValue(style->pageBreakBefore());
2760         case CSSPropertyPageBreakInside: {
2761             EPageBreak pageBreak = style->pageBreakInside();
2762             ASSERT(pageBreak != PBALWAYS);
2763             if (pageBreak == PBALWAYS)
2764                 return nullptr;
2765             return cssValuePool.createValue(style->pageBreakInside());
2766         }
2767         case CSSPropertyPosition:
2768             return cssValuePool.createValue(style->position());
2769         case CSSPropertyRight:
2770             return positionOffsetValue(*style, CSSPropertyRight);
2771         case CSSPropertyWebkitRubyPosition:
2772             return cssValuePool.createValue(style->rubyPosition());
2773         case CSSPropertyTableLayout:
2774             return cssValuePool.createValue(style->tableLayout());
2775         case CSSPropertyTextAlign:
2776             return cssValuePool.createValue(style->textAlign());
2777         case CSSPropertyTextDecoration:
2778             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2779 #if ENABLE(CSS3_TEXT)
2780         case CSSPropertyWebkitTextAlignLast:
2781             return cssValuePool.createValue(style->textAlignLast());
2782         case CSSPropertyWebkitTextJustify:
2783             return cssValuePool.createValue(style->textJustify());
2784 #endif // CSS3_TEXT
2785         case CSSPropertyWebkitTextDecoration:
2786             return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand());
2787         case CSSPropertyWebkitTextDecorationLine:
2788             return renderTextDecorationFlagsToCSSValue(style->textDecoration());
2789         case CSSPropertyWebkitTextDecorationStyle:
2790             return renderTextDecorationStyleFlagsToCSSValue(style->textDecorationStyle());
2791         case CSSPropertyWebkitTextDecorationColor:
2792             return currentColorOrValidColor(style.get(), style->textDecorationColor());
2793         case CSSPropertyWebkitTextDecorationSkip:
2794             return renderTextDecorationSkipFlagsToCSSValue(style->textDecorationSkip());
2795         case CSSPropertyWebkitTextUnderlinePosition:
2796             return cssValuePool.createValue(style->textUnderlinePosition());
2797         case CSSPropertyWebkitTextDecorationsInEffect:
2798             return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
2799         case CSSPropertyWebkitTextFillColor:
2800             return currentColorOrValidColor(style.get(), style->textFillColor());
2801         case CSSPropertyWebkitTextEmphasisColor:
2802             return currentColorOrValidColor(style.get(), style->textEmphasisColor());
2803         case CSSPropertyWebkitTextEmphasisPosition:
2804             return renderEmphasisPositionFlagsToCSSValue(style->textEmphasisPosition());
2805         case CSSPropertyWebkitTextEmphasisStyle:
2806             switch (style->textEmphasisMark()) {
2807             case TextEmphasisMarkNone:
2808                 return cssValuePool.createIdentifierValue(CSSValueNone);
2809             case TextEmphasisMarkCustom:
2810                 return cssValuePool.createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
2811             case TextEmphasisMarkAuto:
2812                 ASSERT_NOT_REACHED();
2813 #if ASSERT_DISABLED
2814                 FALLTHROUGH;
2815 #endif
2816             case TextEmphasisMarkDot:
2817             case TextEmphasisMarkCircle:
2818             case TextEmphasisMarkDoubleCircle:
2819             case TextEmphasisMarkTriangle:
2820             case TextEmphasisMarkSesame: {
2821                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2822                 list->append(cssValuePool.createValue(style->textEmphasisFill()));
2823                 list->append(cssValuePool.createValue(style->textEmphasisMark()));
2824                 return list;
2825             }
2826             }
2827         case CSSPropertyTextIndent: {
2828             // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>),
2829             // getPropertyCSSValue() returns CSSValue.
2830             RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
2831 #if ENABLE(CSS3_TEXT)
2832             // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging,
2833             // getPropertyCSSValue() returns CSSValueList.
2834             if (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging) {
2835                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
2836                 list->append(textIndent.releaseNonNull());
2837                 if (style->textIndentLine() == TextIndentEachLine)
2838                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine));
2839                 if (style->textIndentType() == TextIndentHanging)
2840                     list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging));
2841                 return list;
2842             }
2843 #endif
2844             return textIndent;
2845         }
2846         case CSSPropertyTextShadow:
2847             return valueForShadow(style->textShadow(), propertyID, *style);
2848         case CSSPropertyTextRendering:
2849             return cssValuePool.createValue(style->fontDescription().textRenderingMode());
2850         case CSSPropertyTextOverflow:
2851             if (style->textOverflow())
2852                 return cssValuePool.createIdentifierValue(CSSValueEllipsis);
2853             return cssValuePool.createIdentifierValue(CSSValueClip);
2854         case CSSPropertyWebkitTextSecurity:
2855             return cssValuePool.createValue(style->textSecurity());
2856 #if ENABLE(IOS_TEXT_AUTOSIZING)
2857         case CSSPropertyWebkitTextSizeAdjust:
2858             if (style->textSizeAdjust().isAuto())
2859                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2860             if (style->textSizeAdjust().isNone())
2861                 return cssValuePool.createIdentifierValue(CSSValueNone);
2862             return CSSPrimitiveValue::create(style->textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE);
2863 #endif
2864         case CSSPropertyWebkitTextStrokeColor:
2865             return currentColorOrValidColor(style.get(), style->textStrokeColor());
2866         case CSSPropertyWebkitTextStrokeWidth:
2867             return zoomAdjustedPixelValue(style->textStrokeWidth(), *style);
2868         case CSSPropertyTextTransform:
2869             return cssValuePool.createValue(style->textTransform());
2870         case CSSPropertyTop:
2871             return positionOffsetValue(*style, CSSPropertyTop);
2872         case CSSPropertyUnicodeBidi:
2873             return cssValuePool.createValue(style->unicodeBidi());
2874         case CSSPropertyVerticalAlign:
2875             switch (style->verticalAlign()) {
2876                 case BASELINE:
2877                     return cssValuePool.createIdentifierValue(CSSValueBaseline);
2878                 case MIDDLE:
2879                     return cssValuePool.createIdentifierValue(CSSValueMiddle);
2880                 case SUB:
2881                     return cssValuePool.createIdentifierValue(CSSValueSub);
2882                 case SUPER:
2883                     return cssValuePool.createIdentifierValue(CSSValueSuper);
2884                 case TEXT_TOP:
2885                     return cssValuePool.createIdentifierValue(CSSValueTextTop);
2886                 case TEXT_BOTTOM:
2887                     return cssValuePool.createIdentifierValue(CSSValueTextBottom);
2888                 case TOP:
2889                     return cssValuePool.createIdentifierValue(CSSValueTop);
2890                 case BOTTOM:
2891                     return cssValuePool.createIdentifierValue(CSSValueBottom);
2892                 case BASELINE_MIDDLE:
2893                     return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle);
2894                 case LENGTH:
2895                     return cssValuePool.createValue(style->verticalAlignLength());
2896             }
2897             ASSERT_NOT_REACHED();
2898             return nullptr;
2899         case CSSPropertyVisibility:
2900             return cssValuePool.createValue(style->visibility());
2901         case CSSPropertyWhiteSpace:
2902             return cssValuePool.createValue(style->whiteSpace());
2903         case CSSPropertyWidows:
2904             if (style->hasAutoWidows())
2905                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2906             return cssValuePool.createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
2907         case CSSPropertyWidth:
2908             if (renderer && !renderer->isRenderSVGModelObject()) {
2909                 // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property,
2910                 // the "width" property does not apply for non-replaced inline elements.
2911                 if (!renderer->isReplaced() && renderer->isInline())
2912                     return cssValuePool.createIdentifierValue(CSSValueAuto);
2913                 return zoomAdjustedPixelValue(sizingBox(*renderer).width(), *style);
2914             }
2915             return zoomAdjustedPixelValueForLength(style->width(), *style);
2916         case CSSPropertyWillChange:
2917             return getWillChangePropertyValue(style->willChange());
2918             break;
2919         case CSSPropertyWordBreak:
2920             return cssValuePool.createValue(style->wordBreak());
2921         case CSSPropertyWordSpacing:
2922             return zoomAdjustedPixelValue(style->fontCascade().wordSpacing(), *style);
2923         case CSSPropertyWordWrap:
2924             return cssValuePool.createValue(style->overflowWrap());
2925         case CSSPropertyWebkitLineBreak:
2926             return cssValuePool.createValue(style->lineBreak());
2927         case CSSPropertyWebkitNbspMode:
2928             return cssValuePool.createValue(style->nbspMode());
2929         case CSSPropertyResize:
2930             return cssValuePool.createValue(style->resize());
2931         case CSSPropertyWebkitFontKerning:
2932             return cssValuePool.createValue(style->fontDescription().kerning());
2933         case CSSPropertyWebkitFontSmoothing:
2934             return cssValuePool.createValue(style->fontDescription().fontSmoothing());
2935         case CSSPropertyFontVariantLigatures:
2936             return fontVariantLigaturesPropertyValue(style->fontDescription().variantCommonLigatures(), style->fontDescription().variantDiscretionaryLigatures(), style->fontDescription().variantHistoricalLigatures(), style->fontDescription().variantContextualAlternates());
2937         case CSSPropertyFontVariantPosition:
2938             return fontVariantPositionPropertyValue(style->fontDescription().variantPosition());
2939         case CSSPropertyFontVariantCaps:
2940             return fontVariantCapsPropertyValue(style->fontDescription().variantCaps());
2941         case CSSPropertyFontVariantNumeric:
2942             return fontVariantNumericPropertyValue(style->fontDescription().variantNumericFigure(), style->fontDescription().variantNumericSpacing(), style->fontDescription().variantNumericFraction(), style->fontDescription().variantNumericOrdinal(), style->fontDescription().variantNumericSlashedZero());
2943         case CSSPropertyFontVariantAlternates:
2944             return fontVariantAlternatesPropertyValue(style->fontDescription().variantAlternates());
2945         case CSSPropertyFontVariantEastAsian:
2946             return fontVariantEastAsianPropertyValue(style->fontDescription().variantEastAsianVariant(), style->fontDescription().variantEastAsianWidth(), style->fontDescription().variantEastAsianRuby());
2947         case CSSPropertyZIndex:
2948             if (style->hasAutoZIndex())
2949                 return cssValuePool.createIdentifierValue(CSSValueAuto);
2950             return cssValuePool.createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
2951         case CSSPropertyZoom:
2952             return cssValuePool.createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
2953         case CSSPropertyBoxSizing:
2954             if (style->boxSizing() == CONTENT_BOX)
2955                 return cssValuePool.createIdentifierValue(CSSValueContentBox);
2956             return cssValuePool.createIdentifierValue(CSSValueBorderBox);
2957 #if ENABLE(DASHBOARD_SUPPORT)
2958         case CSSPropertyWebkitDashboardRegion:
2959         {
2960             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
2961             unsigned count = regions.size();
2962             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
2963                 return cssValuePool.createIdentifierValue(CSSValueNone);
2964
2965             RefPtr<DashboardRegion> firstRegion;
2966             DashboardRegion* previousRegion = nullptr;
2967             for (unsigned i = 0; i < count; i++) {
2968                 auto region = DashboardRegion::create();
2969                 StyleDashboardRegion styleRegion = regions[i];
2970
2971                 region->m_label = styleRegion.label;
2972                 LengthBox offset = styleRegion.offset;
2973                 region->setTop(zoomAdjustedPixelValue(offset.top().value(), *style));
2974                 region->setRight(zoomAdjustedPixelValue(offset.right().value(), *style));
2975                 region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), *style));
2976                 region->setLeft(zoomAdjustedPixelValue(offset.left().value(), *style));
2977                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
2978                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
2979
2980                 if (previousRegion)
2981                     previousRegion->m_next = region.copyRef();
2982                 else
2983                     firstRegion = region.copyRef();
2984                 previousRegion = region.ptr();
2985             }
2986             return cssValuePool.createValue(WTF::move(firstRegion));
2987         }
2988 #endif
2989         case CSSPropertyAnimationDelay:
2990         case CSSPropertyWebkitAnimationDelay:
2991             return getDelayValue(style->animations());
2992         case CSSPropertyAnimationDirection:
2993         case CSSPropertyWebkitAnimationDirection: {
2994             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
2995             const AnimationList* t = style->animations();
2996             if (t) {
2997                 for (size_t i = 0; i < t->size(); ++i) {
2998                     switch (t->animation(i).direction()) {
2999                     case Animation::AnimationDirectionNormal:
3000                         list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3001                         break;
3002                     case Animation::AnimationDirectionAlternate:
3003                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternate));
3004                         break;
3005                     case Animation::AnimationDirectionReverse:
3006                         list->append(cssValuePool.createIdentifierValue(CSSValueReverse));
3007                         break;
3008                     case Animation::AnimationDirectionAlternateReverse:
3009                         list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse));
3010                         break;
3011                     }
3012                 }
3013             } else
3014                 list->append(cssValuePool.createIdentifierValue(CSSValueNormal));
3015             return list;
3016         }
3017         case CSSPropertyAnimationDuration:
3018         case CSSPropertyWebkitAnimationDuration:
3019             return getDurationValue(style->animations());
3020         case CSSPropertyAnimationFillMode:
3021         case CSSPropertyWebkitAnimationFillMode: {
3022             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3023             const AnimationList* t = style->animations();
3024             if (t) {
3025                 for (size_t i = 0; i < t->size(); ++i) {
3026                     switch (t->animation(i).fillMode()) {
3027                     case AnimationFillModeNone:
3028                         list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3029                         break;
3030                     case AnimationFillModeForwards:
3031                         list->append(cssValuePool.createIdentifierValue(CSSValueForwards));
3032                         break;
3033                     case AnimationFillModeBackwards:
3034                         list->append(cssValuePool.createIdentifierValue(CSSValueBackwards));
3035                         break;
3036                     case AnimationFillModeBoth:
3037                         list->append(cssValuePool.createIdentifierValue(CSSValueBoth));
3038                         break;
3039                     }
3040                 }
3041             } else
3042                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3043             return list;
3044         }
3045         case CSSPropertyAnimationIterationCount:
3046         case CSSPropertyWebkitAnimationIterationCount: {
3047             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3048             const AnimationList* t = style->animations();
3049             if (t) {
3050                 for (size_t i = 0; i < t->size(); ++i) {
3051                     double iterationCount = t->animation(i).iterationCount();
3052                     if (iterationCount == Animation::IterationCountInfinite)
3053                         list->append(cssValuePool.createIdentifierValue(CSSValueInfinite));
3054                     else
3055                         list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
3056                 }
3057             } else
3058                 list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
3059             return list;
3060         }
3061         case CSSPropertyAnimationName:
3062         case CSSPropertyWebkitAnimationName: {
3063             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3064             const AnimationList* t = style->animations();
3065             if (t) {
3066                 for (size_t i = 0; i < t->size(); ++i)
3067                     list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING));
3068             } else
3069                 list->append(cssValuePool.createIdentifierValue(CSSValueNone));
3070             return list;
3071         }
3072         case CSSPropertyAnimationPlayState:
3073         case CSSPropertyWebkitAnimationPlayState: {
3074             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3075             const AnimationList* t = style->animations();
3076             if (t) {
3077                 for (size_t i = 0; i < t->size(); ++i) {
3078                     int prop = t->animation(i).playState();
3079                     if (prop == AnimPlayStatePlaying)
3080                         list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3081                     else
3082                         list->append(cssValuePool.createIdentifierValue(CSSValuePaused));
3083                 }
3084             } else
3085                 list->append(cssValuePool.createIdentifierValue(CSSValueRunning));
3086             return list;
3087         }
3088         case CSSPropertyAnimationTimingFunction:
3089         case CSSPropertyWebkitAnimationTimingFunction:
3090             return getTimingFunctionValue(style->animations());
3091 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3092         case CSSPropertyWebkitAnimationTrigger:
3093             return getAnimationTriggerValue(style->animations(), *style);
3094 #endif
3095         case CSSPropertyWebkitAppearance:
3096             return cssValuePool.createValue(style->appearance());
3097         case CSSPropertyWebkitAspectRatio:
3098             if (style->aspectRatioType() == AspectRatioAuto)
3099                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3100             if (style->aspectRatioType() == AspectRatioFromDimensions)
3101                 return cssValuePool.createIdentifierValue(CSSValueFromDimensions);
3102             if (style->aspectRatioType() == AspectRatioFromIntrinsic)
3103                 return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic);
3104             return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
3105         case CSSPropertyWebkitBackfaceVisibility:
3106             return cssValuePool.createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
3107         case CSSPropertyWebkitBorderImage:
3108             return valueForNinePieceImage(style->borderImage());
3109         case CSSPropertyBorderImageOutset:
3110             return valueForNinePieceImageQuad(style->borderImage().outset());
3111         case CSSPropertyBorderImageRepeat:
3112             return valueForNinePieceImageRepeat(style->borderImage());
3113         case CSSPropertyBorderImageSlice:
3114             return valueForNinePieceImageSlice(style->borderImage());
3115         case CSSPropertyBorderImageWidth:
3116             return valueForNinePieceImageQuad(style->borderImage().borderSlices());
3117         case CSSPropertyWebkitMaskBoxImage:
3118             return valueForNinePieceImage(style->maskBoxImage());
3119         case CSSPropertyWebkitMaskBoxImageOutset:
3120             return valueForNinePieceImageQuad(style->maskBoxImage().outset());
3121         case CSSPropertyWebkitMaskBoxImageRepeat:
3122             return valueForNinePieceImageRepeat(style->maskBoxImage());
3123         case CSSPropertyWebkitMaskBoxImageSlice:
3124             return valueForNinePieceImageSlice(style->maskBoxImage());
3125         case CSSPropertyWebkitMaskBoxImageWidth:
3126             return valueForNinePieceImageQuad(style->maskBoxImage().borderSlices());
3127         case CSSPropertyWebkitMaskBoxImageSource:
3128             if (style->maskBoxImageSource())
3129                 return style->maskBoxImageSource()->cssValue();
3130             return cssValuePool.createIdentifierValue(CSSValueNone);
3131         case CSSPropertyWebkitFontSizeDelta:
3132             // Not a real style property -- used by the editing engine -- so has no computed value.
3133             break;
3134         case CSSPropertyWebkitInitialLetter: {
3135             RefPtr<CSSPrimitiveValue> drop = !style->initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER);
3136             RefPtr<CSSPrimitiveValue> size = !style->initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style->initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER);
3137             return cssValuePool.createValue(Pair::create(drop.release(), size.release()));
3138         }
3139         case CSSPropertyWebkitMarginBottomCollapse:
3140         case CSSPropertyWebkitMarginAfterCollapse:
3141             return cssValuePool.createValue(style->marginAfterCollapse());
3142         case CSSPropertyWebkitMarginTopCollapse:
3143         case CSSPropertyWebkitMarginBeforeCollapse:
3144             return cssValuePool.createValue(style->marginBeforeCollapse());
3145 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
3146         case CSSPropertyWebkitOverflowScrolling:
3147             if (!style->useTouchOverflowScrolling())
3148                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3149             return cssValuePool.createIdentifierValue(CSSValueTouch);
3150 #endif
3151         case CSSPropertyPerspective:
3152             if (!style->hasPerspective())
3153                 return cssValuePool.createIdentifierValue(CSSValueNone);
3154             return zoomAdjustedPixelValue(style->perspective(), *style);
3155         case CSSPropertyPerspectiveOrigin: {
3156             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3157             if (renderer) {
3158                 LayoutRect box;
3159                 if (is<RenderBox>(*renderer))
3160                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3161
3162                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
3163                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
3164             }
3165             else {
3166                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
3167                 list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), *style));
3168
3169             }
3170             return list;
3171         }
3172         case CSSPropertyWebkitRtlOrdering:
3173             return cssValuePool.createIdentifierValue(style->rtlOrdering() ? CSSValueVisual : CSSValueLogical);
3174 #if ENABLE(TOUCH_EVENTS)
3175         case CSSPropertyWebkitTapHighlightColor:
3176             return currentColorOrValidColor(style.get(), style->tapHighlightColor());
3177 #endif
3178 #if PLATFORM(IOS)
3179         case CSSPropertyWebkitTouchCallout:
3180             return cssValuePool.createIdentifierValue(style->touchCalloutEnabled() ? CSSValueDefault : CSSValueNone);
3181 #endif
3182         case CSSPropertyWebkitUserDrag:
3183             return cssValuePool.createValue(style->userDrag());
3184         case CSSPropertyWebkitUserSelect:
3185             return cssValuePool.createValue(style->userSelect());
3186         case CSSPropertyBorderBottomLeftRadius:
3187             return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), *style);
3188         case CSSPropertyBorderBottomRightRadius:
3189             return getBorderRadiusCornerValue(style->borderBottomRightRadius(), *style);
3190         case CSSPropertyBorderTopLeftRadius:
3191             return getBorderRadiusCornerValue(style->borderTopLeftRadius(), *style);
3192         case CSSPropertyBorderTopRightRadius:
3193             return getBorderRadiusCornerValue(style->borderTopRightRadius(), *style);
3194         case CSSPropertyClip: {
3195             if (!style->hasClip())
3196                 return cssValuePool.createIdentifierValue(CSSValueAuto);
3197             auto rect = Rect::create();
3198             rect->setTop(autoOrZoomAdjustedValue(style->clip().top(), *style));
3199             rect->setRight(autoOrZoomAdjustedValue(style->clip().right(), *style));
3200             rect->setBottom(autoOrZoomAdjustedValue(style->clip().bottom(), *style));
3201             rect->setLeft(autoOrZoomAdjustedValue(style->clip().left(), *style));
3202             return cssValuePool.createValue(WTF::move(rect));
3203         }
3204         case CSSPropertySpeak:
3205             return cssValuePool.createValue(style->speak());
3206         case CSSPropertyTransform:
3207             return computedTransform(renderer, *style);
3208         case CSSPropertyTransformOrigin: {
3209             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3210             if (renderer) {
3211                 LayoutRect box;
3212                 if (is<RenderBox>(*renderer))
3213                     box = downcast<RenderBox>(*renderer).borderBoxRect();
3214
3215                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
3216                 list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
3217                 if (style->transformOriginZ() != 0)
3218                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3219             } else {
3220                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), *style));
3221                 list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), *style));
3222                 if (style->transformOriginZ() != 0)
3223                     list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
3224             }
3225             return list;
3226         }
3227         case CSSPropertyTransformStyle:
3228         case CSSPropertyWebkitTransformStyle:
3229             return cssValuePool.createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
3230         case CSSPropertyTransitionDelay:
3231         case CSSPropertyWebkitTransitionDelay:
3232             return getDelayValue(style->transitions());
3233         case CSSPropertyTransitionDuration:
3234         case CSSPropertyWebkitTransitionDuration:
3235             return getDurationValue(style->transitions());
3236         case CSSPropertyTransitionProperty:
3237         case CSSPropertyWebkitTransitionProperty:
3238             return getTransitionPropertyValue(style->transitions());
3239         case CSSPropertyTransitionTimingFunction:
3240         case CSSPropertyWebkitTransitionTimingFunction:
3241             return getTimingFunctionValue(style->transitions());
3242         case CSSPropertyTransition:
3243         case CSSPropertyWebkitTransition: {
3244             const AnimationList* animList = style->transitions();
3245             if (animList) {
3246                 RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
3247                 for (size_t i = 0; i < animList->size(); ++i) {
3248                     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3249                     const Animation& animation = animList->animation(i);
3250                     list->append(createTransitionPropertyValue(animation));
3251                     list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S));
3252                     list->append(createTimingFunctionValue(animation.timingFunction().get()));
3253                     list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S));
3254                     transitionsList->append(list.releaseNonNull());
3255                 }
3256                 return transitionsList;
3257             }
3258
3259             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3260             // transition-property default value.
3261             list->append(cssValuePool.createIdentifierValue(CSSValueAll));
3262             list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S));
3263             list->append(createTimingFunctionValue(Animation::initialTimingFunction().get()));
3264             list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S));
3265             return list;
3266         }
3267         case CSSPropertyPointerEvents:
3268             return cssValuePool.createValue(style->pointerEvents());
3269         case CSSPropertyWebkitLineGrid:
3270             if (style->lineGrid().isNull())
3271                 return cssValuePool.createIdentifierValue(CSSValueNone);
3272             return cssValuePool.createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
3273         case CSSPropertyWebkitLineSnap:
3274             return CSSPrimitiveValue::create(style->lineSnap());
3275         case CSSPropertyWebkitLineAlign:
3276             return CSSPrimitiveValue::create(style->lineAlign());
3277         case CSSPropertyWebkitWritingMode:
3278             return cssValuePool.createValue(style->writingMode());
3279         case CSSPropertyWebkitTextCombine:
3280             return cssValuePool.createValue(style->textCombine());
3281         case CSSPropertyWebkitTextOrientation:
3282             return CSSPrimitiveValue::create(style->textOrientation());
3283         case CSSPropertyWebkitLineBoxContain:
3284             return createLineBoxContainValue(style->lineBoxContain());
3285         case CSSPropertyAlt:
3286             return altTextToCSSValue(style.get());
3287         case CSSPropertyContent:
3288             return contentToCSSValue(style.get());
3289         case CSSPropertyCounterIncrement:
3290             return counterToCSSValue(style.get(), propertyID);
3291         case CSSPropertyCounterReset:
3292             return counterToCSSValue(style.get(), propertyID);
3293         case CSSPropertyWebkitClipPath: {
3294             ClipPathOperation* operation = style->clipPath();
3295             if (!operation)
3296                 return cssValuePool.createIdentifierValue(CSSValueNone);
3297             if (is<ReferenceClipPathOperation>(*operation)) {
3298                 const auto& referenceOperation = downcast<ReferenceClipPathOperation>(*operation);
3299                 return CSSPrimitiveValue::create(referenceOperation.url(), CSSPrimitiveValue::CSS_URI);
3300             }
3301             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
3302             if (is<ShapeClipPathOperation>(*operation)) {
3303                 const auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation);
3304                 list->append(valueForBasicShape(*style, shapeOperation.basicShape()));
3305                 if (shapeOperation.referenceBox() != BoxMissing)
3306                     list->append(cssValuePool.createValue(shapeOperation.referenceBox()));
3307             }
3308             if (is<BoxClipPathOperation>(*operation)) {
3309                 const auto& boxOperation = downcast<BoxClipPathOperation>(*operation);
3310                 list->append(cssValuePool.createValue(boxOperation.referenceBox()));
3311             }
3312             return list;
3313         }
3314 #if ENABLE(CSS_REGIONS)
3315         case CSSPropertyWebkitFlowInto:
3316             if (!style->hasFlowInto())
3317                 return cssValuePool.createIdentifierValue(CSSValueNone);
3318             return cssValuePool.createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
3319         case CSSPropertyWebkitFlowFrom:
3320             if (!style->hasFlowFrom())
3321                 return cssValuePool.createIdentifierValue(CSSValueNone);
3322             return cssValuePool.createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
3323         case CSSPropertyWebkitRegionFragment:
3324             return cssValuePool.createValue(style->regionFragment());
3325 #endif
3326 #if ENABLE(CSS_SHAPES)
3327         case CSSPropertyWebkitShapeMargin:
3328             return cssValuePool.createValue(style->shapeMargin(), *style);
3329         case CSSPropertyWebkitShapeImageThreshold:
3330             return cssValuePool.createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
3331         case CSSPropertyWebkitShapeOutside:
3332             return shapePropertyValue(*style, style->shapeOutside());
3333 #endif
3334         case CSSPropertyFilter:
3335             return valueForFilter(*style, style->filter());
3336 #if ENABLE(FILTERS_LEVEL_2)
3337         case CSSPropertyWebkitBackdropFilter:
3338             return valueForFilter(*style, style->backdropFilter());
3339 #endif
3340 #if ENABLE(CSS_COMPOSITING)
3341         case CSSPropertyMixBlendMode:
3342             return cssValuePool.createValue(style->blendMode());
3343         case CSSPropertyIsolation:
3344             return cssValuePool.createValue(style->isolation());
3345 #endif
3346         case CSSPropertyBackgroundBlendMode: {
3347             const FillLayer* layers = style->backgroundLayers();
3348             if (!layers->next())
3349                 return cssValuePool.createValue(layers->blendMode());
3350
3351             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
3352             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
3353                 list->append(cssValuePool.createValue(currLayer->blendMode()));
3354
3355             return list.release();
3356         }
3357         case CSSPropertyBackground:
3358             return getBackgroundShorthandValue();
3359         case CSSPropertyBorder: {
3360             RefPtr<CSSValue> value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout);
3361             const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
3362             for (auto& property : properties) {
3363                 if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout)))
3364                     return nullptr;
3365             }
3366             return value;
3367         }
3368         case CSSPropertyBorderBottom:
3369             return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand());
3370         case CSSPropertyBorderColor:
3371             return getCSSPropertyValuesForSidesShorthand(borderColorShorthand());
3372         case CSSPropertyBorderLeft:
3373             return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand());
3374         case CSSPropertyBorderImage:
3375             return valueForNinePieceImage(style->borderImage());
3376         case CSSPropertyBorderRadius:
3377             return getBorderRadiusShorthandValue(*style);
3378         case CSSPropertyBorderRight:
3379             return getCSSPropertyValuesForShorthandProperties(borderRightShorthand());
3380         case CSSPropertyBorderStyle:
3381             return getCSSPropertyValuesForSidesShorthand(borderStyleShorthand());
3382         case CSSPropertyBorderTop:
3383             return getCSSPropertyValuesForShorthandProperties(borderTopShorthand());
3384         case CSSPropertyBorderWidth:
3385             return getCSSPropertyValuesForSidesShorthand(borderWidthShorthand());
3386         case CSSPropertyColumnRule:
3387             return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand());
3388         case CSSPropertyColumns:
3389             return getCSSPropertyValuesForShorthandProperties(columnsShorthand());
3390         case CSSPropertyListStyle:
3391             return getCSSPropertyValuesForShorthandProperties(listStyleShorthand());
3392         case CSSPropertyMargin:
3393             return getCSSPropertyValuesForSidesShorthand(marginShorthand());
3394         case CSSPropertyOutline:
3395             return getCSSPropertyValuesForShorthandProperties(outlineShorthand());
3396         case CSSPropertyPadding:
3397             return getCSSPropertyValuesForSidesShorthand(paddingShorthand());
3398
3399 #if ENABLE(CSS_SCROLL_SNAP)
3400         case CSSPropertyWebkitScrollSnapType:
3401             return cssValuePool.createValue(style->scrollSnapType());
3402         case CSSPropertyWebkitScrollSnapDestination:
3403             return scrollSnapDestination(*style, style->scrollSnapDestination());
3404         case CSSPropertyWebkitScrollSnapPointsX:
3405             return scrollSnapPoints(*style, style->scrollSnapPointsX());
3406         case CSSPropertyWebkitScrollSnapPointsY:
3407             return scrollSnapPoints(*style, style->scrollSnapPointsY());
3408         case CSSPropertyWebkitScrollSnapCoordinate:
3409             return scrollSnapCoordinates(*style, style->scrollSnapCoordinates());
3410 #endif
3411
3412 #if ENABLE(CSS_TRAILING_WORD)
3413         case CSSPropertyAppleTrailingWord:
3414             return cssValuePool.createValue(style->trailingWord());
3415 #endif
3416
3417         /* Individual properties not part of the spec */
3418         case CSSPropertyBackgroundRepeatX:
3419         case CSSPropertyBackgroundRepeatY:
3420             break;
3421
3422         // Length properties for SVG.
3423         case CSSPropertyCx:
3424             return zoomAdjustedPixelValueForLength(style->svgStyle().cx(), *style);
3425         case CSSPropertyCy:
3426             return zoomAdjustedPixelValueForLength(style->svgStyle().cy(), *style);
3427         case CSSPropertyR:
3428             return zoomAdjustedPixelValueForLength(style->svgStyle().r(), *style);
3429         case CSSPropertyRx:
3430             return zoomAdjustedPixelValueForLength(style->svgStyle().rx(), *style);
3431         case CSSPropertyRy:
3432             return zoomAdjustedPixelValueForLength(style->svgStyle().ry(), *style);
3433         case CSSPropertyStrokeWidth:
3434             return zoomAdjustedPixelValueForLength(style->svgStyle().strokeWidth(), *style);
3435         case CSSPropertyStrokeDashoffset:
3436             return zoomAdjustedPixelValueForLength(style->svgStyle().strokeDashOffset(), *style);
3437         case CSSPropertyX:
3438             return zoomAdjustedPixelValueForLength(style->svgStyle().x(), *style);
3439         case CSSPropertyY:
3440             return zoomAdjustedPixelValueForLength(style->svgStyle().y(), *style);
3441         case CSSPropertyWebkitTextZoom:
3442             return cssValuePool.createValue(style->textZoom());
3443
3444         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
3445         case CSSPropertyAnimation:
3446         case CSSPropertyWebkitTextEmphasis:
3447         case CSSPropertyTextLineThrough:
3448         case CSSPropertyTextLineThroughColor:
3449         case CSSPropertyTextLineThroughMode:
3450         case CSSPropertyTextLineThroughStyle:
3451         case CSSPropertyTextLineThroughWidth:
3452         case CSSPropertyTextOverline:
3453         case CSSPropertyTextOverlineColor:
3454         case CSSPropertyTextOverlineMode:
3455         case CSSPropertyTextOverlineStyle:
3456         case CSSPropertyTextOverlineWidth:
3457         case CSSPropertyTextUnderline:
3458         case CSSPropertyTextUnderlineColor:
3459         case CSSPropertyTextUnderlineMode:
3460         case CSSPropertyTextUnderlineStyle:
3461         case CSSPropertyTextUnderlineWidth:
3462             break;
3463
3464         /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */
3465         case CSSPropertyWebkitBorderEnd:
3466         case CSSPropertyWebkitBorderEndColor:
3467         case CSSPropertyWebkitBorderEndStyle:
3468         case CSSPropertyWebkitBorderEndWidth:
3469         case CSSPropertyWebkitBorderStart:
3470         case CSSPropertyWebkitBorderStartColor:
3471         case CSSPropertyWebkitBorderStartStyle:
3472         case CSSPropertyWebkitBorderStartWidth:
3473         case CSSPropertyWebkitBorderAfter:
3474         case CSSPropertyWebkitBorderAfterColor:
3475         case CSSPropertyWebkitBorderAfterStyle:
3476         case CSSPropertyWebkitBorderAfterWidth:
3477         case CSSPropertyWebkitBorderBefore:
3478         case CSSPropertyWebkitBorderBeforeColor:
3479         case CSSPropertyWebkitBorderBeforeStyle:
3480         case CSSPropertyWebkitBorderBeforeWidth:
3481         case CSSPropertyWebkitMarginEnd:
3482         case CSSPropertyWebkitMarginStart:
3483         case CSSPropertyWebkitMarginAfter:
3484         case CSSPropertyWebkitMarginBefore:
3485         case CSSPropertyWebkitPaddingEnd:
3486         case CSSPropertyWebkitPaddingStart:
3487         case CSSPropertyWebkitPaddingAfter:
3488         case CSSPropertyWebkitPaddingBefore:
3489         case CSSPropertyWebkitLogicalWidth:
3490         case CSSPropertyWebkitLogicalHeight:
3491         case CSSPropertyWebkitMinLogicalWidth:
3492         case CSSPropertyWebkitMinLogicalHeight:
3493         case CSSPropertyWebkitMaxLogicalWidth:
3494         case CSSPropertyWebkitMaxLogicalHeight:
3495             ASSERT_NOT_REACHED();
3496             break;
3497
3498         /* Unimplemented @font-face properties */
3499         case CSSPropertyFontStretch:
3500         case CSSPropertySrc:
3501         case CSSPropertyUnicodeRange:
3502             break;
3503
3504         /* Other unimplemented properties */
3505         case CSSPropertyPage: // for @page
3506         case CSSPropertyQuotes: // FIXME: needs implementation
3507         case CSSPropertySize: // for @page
3508             break;
3509
3510         /* Unimplemented -webkit- properties */
3511         case CSSPropertyWebkitAnimation:
3512         case CSSPropertyWebkitBorderRadius:
3513         case CSSPropertyWebkitMarginCollapse:
3514         case CSSPropertyWebkitMarquee:
3515         case CSSPropertyWebkitMarqueeSpeed:
3516         case CSSPropertyWebkitMask:
3517         case CSSPropertyWebkitMaskRepeatX:
3518         case CSSPropertyWebkitMaskRepeatY:
3519         case CSSPropertyPerspectiveOriginX:
3520         case CSSPropertyPerspectiveOriginY:
3521         case CSSPropertyWebkitTextStroke:
3522         case CSSPropertyTransformOriginX:
3523         case CSSPropertyTransformOriginY:
3524         case CSSPropertyTransformOriginZ:
3525             break;
3526
3527 #if ENABLE(CSS_DEVICE_ADAPTATION)
3528         case CSSPropertyMaxZoom:
3529         case CSSPropertyMinZoom:
3530         case CSSPropertyOrientation:
3531         case CSSPropertyUserZoom:
3532             break;
3533 #endif
3534
3535         case CSSPropertyBufferedRendering:
3536         case CSSPropertyClipPath:
3537         case CSSPropertyClipRule:
3538         case CSSPropertyMask:
3539         case CSSPropertyEnableBackground:
3540         case CSSPropertyFloodColor:
3541         case CSSPropertyFloodOpacity:
3542         case CSSPropertyLightingColor:
3543         case CSSPropertyStopColor:
3544         case CSSPropertyStopOpacity:
3545         case CSSPropertyColorInterpolation:
3546         case CSSPropertyColorInterpolationFilters:
3547         case CSSPropertyColorProfile:
3548         case CSSPropertyColorRendering:
3549         case CSSPropertyFill:
3550         case CSSPropertyFillOpacity:
3551         case CSSPropertyFillRule:
3552         case CSSPropertyMarker:
3553         case CSSPropertyMarkerEnd:
3554         case CSSPropertyMarkerMid:
3555         case CSSPropertyMarkerStart:
3556         case CSSPropertyMaskType:
3557         case CSSPropertyPaintOrder:
3558         case CSSPropertyShapeRendering:
3559         case CSSPropertyStroke:
3560         case CSSPropertyStrokeDasharray:
3561         case CSSPropertyStrokeLinecap:
3562         case CSSPropertyStrokeLinejoin:
3563         case CSSPropertyStrokeMiterlimit:
3564         case CSSPropertyStrokeOpacity:
3565         case CSSPropertyAlignmentBaseline:
3566         case CSSPropertyBaselineShift:
3567         case CSSPropertyDominantBaseline:
3568         case CSSPropertyGlyphOrientationHorizontal:
3569         case CSSPropertyGlyphOrientationVertical:
3570         case CSSPropertyKerning:
3571         case CSSPropertyTextAnchor:
3572         case CSSPropertyVectorEffect:
3573         case CSSPropertyWritingMode:
3574         case CSSPropertyWebkitSvgShadow:
3575             return svgPropertyValue(propertyID, DoNotUpdateLayout);
3576         case CSSPropertyCustom:
3577             ASSERT_NOT_REACHED();
3578             return nullptr;
3579     }
3580
3581     logUnimplementedPropertyID(propertyID);
3582     return nullptr;
3583 }
3584
3585 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
3586 {
3587     RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
3588     if (!value)
3589         return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue?
3590     return value->cssText();
3591 }
3592
3593 unsigned CSSComputedStyleDeclaration::length() const
3594 {
3595     Node* node = m_node.get();
3596     if (!node)
3597         return 0;
3598
3599     RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
3600     if (!style)
3601         return 0;
3602
3603     const HashMap<AtomicString, RefPtr<CSSValue>>* customProperties = style->customProperties();
3604     return numComputedProperties + (customProperties ? customProperties->size() : 0);
3605 }
3606
3607 String CSSComputedStyleDeclaration::item(unsigned i) const
3608 {
3609     if (i >= length())
3610         return emptyString();
3611     
3612     if (i < numComputedProperties)
3613         return getPropertyNameString(computedProperties[i]);
3614     
3615     Node* node = m_node.get();
3616     if (!node)
3617         return emptyString();
3618
3619     RenderStyle* style = node->computedStyle(m_pseudoElementSpecifier);
3620     if (!style)
3621         return emptyString();
3622     
3623     unsigned index = i - numComputedProperties;
3624     
3625     const auto* customProperties = style->customProperties();
3626     if (!customProperties || index >= customProperties->size())
3627         return emptyString();
3628     
3629     Vector<String, 4> results;
3630     copyKeysToVector(*customProperties, results);
3631     return results.at(index);
3632 }
3633
3634 bool ComputedStyleExtractor::propertyMatches(CSSPropertyID propertyID, const CSSValue* value) const
3635 {
3636     if (propertyID == CSSPropertyFontSize && is<CSSPrimitiveValue>(*value) && m_node) {
3637         m_node->document().updateLayoutIgnorePendingStylesheets();
3638         if (RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier)) {
3639             if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) {
3640                 auto& primitiveValue = downcast<CSSPrimitiveValue>(*value);
3641                 if (primitiveValue.isValueID() && primitiveValue.getValueID() == sizeIdentifier)
3642                     return true;
3643             }
3644         }
3645     }
3646     RefPtr<CSSValue> computedValue = propertyValue(propertyID);
3647     return computedValue && value && computedValue->equals(*value);