1 | /* |
2 | * Copyright (C) 2004 Zack Rusin <zack@kde.org> |
3 | * Copyright (C) 2004-2019 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 "BasicShapeFunctions.h" |
29 | #include "CSSAnimationController.h" |
30 | #include "CSSAspectRatioValue.h" |
31 | #include "CSSBasicShapes.h" |
32 | #include "CSSBorderImage.h" |
33 | #include "CSSBorderImageSliceValue.h" |
34 | #include "CSSFontFeatureValue.h" |
35 | #include "CSSFontStyleValue.h" |
36 | #include "CSSFontValue.h" |
37 | #include "CSSFontVariationValue.h" |
38 | #include "CSSFunctionValue.h" |
39 | #include "CSSLineBoxContainValue.h" |
40 | #include "CSSPrimitiveValue.h" |
41 | #include "CSSPrimitiveValueMappings.h" |
42 | #include "CSSPropertyNames.h" |
43 | #include "CSSPropertyParser.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 "ComposedTreeAncestorIterator.h" |
51 | #include "ContentData.h" |
52 | #include "CursorList.h" |
53 | #include "DeprecatedCSSOMValue.h" |
54 | #include "Document.h" |
55 | #include "DocumentTimeline.h" |
56 | #include "FontCascade.h" |
57 | #include "FontSelectionValueInlines.h" |
58 | #include "FontTaggedSettings.h" |
59 | #include "NodeRenderStyle.h" |
60 | #include "Pair.h" |
61 | #include "Rect.h" |
62 | #include "RenderBlock.h" |
63 | #include "RenderBox.h" |
64 | #include "RenderInline.h" |
65 | #include "RenderStyle.h" |
66 | #include "RuntimeEnabledFeatures.h" |
67 | #include "SVGElement.h" |
68 | #include "Settings.h" |
69 | #include "ShapeValue.h" |
70 | #include "StyleProperties.h" |
71 | #include "StylePropertyShorthand.h" |
72 | #include "StylePropertyShorthandFunctions.h" |
73 | #include "StyleResolver.h" |
74 | #include "StyleScope.h" |
75 | #include "StyleScrollSnapPoints.h" |
76 | #include "TouchAction.h" |
77 | #include "WebKitFontFamilyNames.h" |
78 | #include "WillChangeData.h" |
79 | #include <wtf/IsoMallocInlines.h> |
80 | #include <wtf/NeverDestroyed.h> |
81 | #include <wtf/text/StringBuilder.h> |
82 | |
83 | #include "CSSGridLineNamesValue.h" |
84 | #include "CSSGridTemplateAreasValue.h" |
85 | #include "RenderGrid.h" |
86 | |
87 | namespace WebCore { |
88 | |
89 | WTF_MAKE_ISO_ALLOCATED_IMPL(CSSComputedStyleDeclaration); |
90 | |
91 | // List of all properties we know how to compute, omitting shorthands. |
92 | static const CSSPropertyID computedProperties[] = { |
93 | CSSPropertyAlignContent, |
94 | CSSPropertyAlignItems, |
95 | CSSPropertyAlignSelf, |
96 | CSSPropertyAlignmentBaseline, |
97 | CSSPropertyAlt, |
98 | CSSPropertyAnimationDelay, |
99 | CSSPropertyAnimationDirection, |
100 | CSSPropertyAnimationDuration, |
101 | CSSPropertyAnimationFillMode, |
102 | CSSPropertyAnimationIterationCount, |
103 | CSSPropertyAnimationName, |
104 | CSSPropertyAnimationPlayState, |
105 | CSSPropertyAnimationTimingFunction, |
106 | CSSPropertyBackgroundAttachment, |
107 | CSSPropertyBackgroundBlendMode, |
108 | CSSPropertyBackgroundClip, |
109 | CSSPropertyBackgroundColor, |
110 | CSSPropertyBackgroundImage, |
111 | CSSPropertyBackgroundOrigin, |
112 | CSSPropertyBackgroundPosition, // more-specific background-position-x/y are non-standard |
113 | CSSPropertyBackgroundRepeat, |
114 | CSSPropertyBackgroundSize, |
115 | CSSPropertyBaselineShift, |
116 | CSSPropertyBorderBottomColor, |
117 | CSSPropertyBorderBottomLeftRadius, |
118 | CSSPropertyBorderBottomRightRadius, |
119 | CSSPropertyBorderBottomStyle, |
120 | CSSPropertyBorderBottomWidth, |
121 | CSSPropertyBorderCollapse, |
122 | CSSPropertyBorderImageOutset, |
123 | CSSPropertyBorderImageRepeat, |
124 | CSSPropertyBorderImageSlice, |
125 | CSSPropertyBorderImageSource, |
126 | CSSPropertyBorderImageWidth, |
127 | CSSPropertyBorderLeftColor, |
128 | CSSPropertyBorderLeftStyle, |
129 | CSSPropertyBorderLeftWidth, |
130 | CSSPropertyBorderRightColor, |
131 | CSSPropertyBorderRightStyle, |
132 | CSSPropertyBorderRightWidth, |
133 | CSSPropertyBorderTopColor, |
134 | CSSPropertyBorderTopLeftRadius, |
135 | CSSPropertyBorderTopRightRadius, |
136 | CSSPropertyBorderTopStyle, |
137 | CSSPropertyBorderTopWidth, |
138 | CSSPropertyBottom, |
139 | CSSPropertyBoxShadow, |
140 | CSSPropertyBoxSizing, |
141 | CSSPropertyBufferedRendering, |
142 | CSSPropertyCaptionSide, |
143 | CSSPropertyCaretColor, |
144 | CSSPropertyClear, |
145 | CSSPropertyClip, |
146 | CSSPropertyClipPath, |
147 | CSSPropertyClipRule, |
148 | CSSPropertyColor, |
149 | CSSPropertyColorInterpolation, |
150 | CSSPropertyColorInterpolationFilters, |
151 | CSSPropertyColorRendering, |
152 | #if ENABLE(DARK_MODE_CSS) |
153 | CSSPropertyColorScheme, |
154 | #endif |
155 | CSSPropertyColumnCount, |
156 | CSSPropertyColumnFill, |
157 | CSSPropertyColumnGap, |
158 | CSSPropertyColumnRuleColor, |
159 | CSSPropertyColumnRuleStyle, |
160 | CSSPropertyColumnRuleWidth, |
161 | CSSPropertyColumnSpan, |
162 | CSSPropertyColumnWidth, |
163 | CSSPropertyContent, |
164 | CSSPropertyCounterIncrement, |
165 | CSSPropertyCounterReset, |
166 | CSSPropertyCursor, |
167 | CSSPropertyCx, |
168 | CSSPropertyCy, |
169 | CSSPropertyDirection, |
170 | CSSPropertyDisplay, |
171 | CSSPropertyDominantBaseline, |
172 | CSSPropertyEmptyCells, |
173 | CSSPropertyFill, |
174 | CSSPropertyFillOpacity, |
175 | CSSPropertyFillRule, |
176 | CSSPropertyFilter, |
177 | CSSPropertyFlexBasis, |
178 | CSSPropertyFlexDirection, |
179 | CSSPropertyFlexFlow, |
180 | CSSPropertyFlexGrow, |
181 | CSSPropertyFlexShrink, |
182 | CSSPropertyFlexWrap, |
183 | CSSPropertyFloat, |
184 | CSSPropertyFloodColor, |
185 | CSSPropertyFloodOpacity, |
186 | CSSPropertyFontFamily, |
187 | #if ENABLE(VARIATION_FONTS) |
188 | CSSPropertyFontOpticalSizing, |
189 | #endif |
190 | CSSPropertyFontSize, |
191 | CSSPropertyFontStretch, |
192 | CSSPropertyFontStyle, |
193 | CSSPropertyFontSynthesis, |
194 | CSSPropertyFontVariant, |
195 | CSSPropertyFontVariantAlternates, |
196 | CSSPropertyFontVariantCaps, |
197 | CSSPropertyFontVariantEastAsian, |
198 | CSSPropertyFontVariantLigatures, |
199 | CSSPropertyFontVariantNumeric, |
200 | CSSPropertyFontVariantPosition, |
201 | #if ENABLE(VARIATION_FONTS) |
202 | CSSPropertyFontVariationSettings, |
203 | #endif |
204 | CSSPropertyFontWeight, |
205 | CSSPropertyGlyphOrientationHorizontal, |
206 | CSSPropertyGlyphOrientationVertical, |
207 | CSSPropertyGridAutoColumns, |
208 | CSSPropertyGridAutoFlow, |
209 | CSSPropertyGridAutoRows, |
210 | CSSPropertyGridColumnEnd, |
211 | CSSPropertyGridColumnStart, |
212 | CSSPropertyGridRowEnd, |
213 | CSSPropertyGridRowStart, |
214 | CSSPropertyGridTemplateAreas, |
215 | CSSPropertyGridTemplateColumns, |
216 | CSSPropertyGridTemplateRows, |
217 | CSSPropertyHangingPunctuation, |
218 | CSSPropertyHeight, |
219 | #if ENABLE(CSS_IMAGE_ORIENTATION) |
220 | CSSPropertyImageOrientation, |
221 | #endif |
222 | CSSPropertyImageRendering, |
223 | #if ENABLE(CSS_IMAGE_RESOLUTION) |
224 | CSSPropertyImageResolution, |
225 | #endif |
226 | #if ENABLE(CSS_COMPOSITING) |
227 | CSSPropertyIsolation, |
228 | #endif |
229 | CSSPropertyJustifyContent, |
230 | CSSPropertyJustifyItems, |
231 | CSSPropertyJustifySelf, |
232 | CSSPropertyKerning, |
233 | CSSPropertyLeft, |
234 | CSSPropertyLetterSpacing, |
235 | CSSPropertyLightingColor, |
236 | CSSPropertyLineBreak, |
237 | CSSPropertyLineHeight, |
238 | CSSPropertyListStyleImage, |
239 | CSSPropertyListStylePosition, |
240 | CSSPropertyListStyleType, |
241 | CSSPropertyMarginBottom, |
242 | CSSPropertyMarginLeft, |
243 | CSSPropertyMarginRight, |
244 | CSSPropertyMarginTop, |
245 | CSSPropertyMarkerEnd, |
246 | CSSPropertyMarkerMid, |
247 | CSSPropertyMarkerStart, |
248 | CSSPropertyMask, |
249 | CSSPropertyMaskType, |
250 | CSSPropertyMaxHeight, |
251 | CSSPropertyMaxWidth, |
252 | CSSPropertyMinHeight, |
253 | CSSPropertyMinWidth, |
254 | #if ENABLE(CSS_COMPOSITING) |
255 | CSSPropertyMixBlendMode, |
256 | #endif |
257 | CSSPropertyObjectFit, |
258 | CSSPropertyObjectPosition, |
259 | CSSPropertyOpacity, |
260 | CSSPropertyOrder, |
261 | CSSPropertyOrphans, |
262 | CSSPropertyOutlineColor, |
263 | CSSPropertyOutlineOffset, |
264 | CSSPropertyOutlineStyle, |
265 | CSSPropertyOutlineWidth, |
266 | CSSPropertyOverflowWrap, |
267 | CSSPropertyOverflowX, |
268 | CSSPropertyOverflowY, |
269 | CSSPropertyPaddingBottom, |
270 | CSSPropertyPaddingLeft, |
271 | CSSPropertyPaddingRight, |
272 | CSSPropertyPaddingTop, |
273 | CSSPropertyPageBreakAfter, |
274 | CSSPropertyPageBreakBefore, |
275 | CSSPropertyPageBreakInside, |
276 | CSSPropertyPaintOrder, |
277 | CSSPropertyPerspective, |
278 | CSSPropertyPerspectiveOrigin, |
279 | CSSPropertyPlaceContent, |
280 | CSSPropertyPlaceItems, |
281 | CSSPropertyPlaceSelf, |
282 | CSSPropertyPointerEvents, |
283 | CSSPropertyPosition, |
284 | CSSPropertyR, |
285 | CSSPropertyResize, |
286 | CSSPropertyRight, |
287 | CSSPropertyRowGap, |
288 | CSSPropertyRx, |
289 | CSSPropertyRy, |
290 | #if ENABLE(CSS_SCROLL_SNAP) |
291 | CSSPropertyScrollPadding, |
292 | CSSPropertyScrollPaddingBottom, |
293 | CSSPropertyScrollPaddingLeft, |
294 | CSSPropertyScrollPaddingRight, |
295 | CSSPropertyScrollPaddingTop, |
296 | CSSPropertyScrollSnapAlign, |
297 | CSSPropertyScrollSnapMargin, |
298 | CSSPropertyScrollSnapMarginBottom, |
299 | CSSPropertyScrollSnapMarginLeft, |
300 | CSSPropertyScrollSnapMarginRight, |
301 | CSSPropertyScrollSnapMarginTop, |
302 | CSSPropertyScrollSnapType, |
303 | #endif |
304 | CSSPropertyShapeImageThreshold, |
305 | CSSPropertyShapeMargin, |
306 | CSSPropertyShapeOutside, |
307 | CSSPropertyShapeRendering, |
308 | CSSPropertySpeakAs, |
309 | CSSPropertyStopColor, |
310 | CSSPropertyStopOpacity, |
311 | CSSPropertyStroke, |
312 | CSSPropertyStrokeColor, |
313 | CSSPropertyStrokeDasharray, |
314 | CSSPropertyStrokeDashoffset, |
315 | CSSPropertyStrokeLinecap, |
316 | CSSPropertyStrokeLinejoin, |
317 | CSSPropertyStrokeMiterlimit, |
318 | CSSPropertyStrokeOpacity, |
319 | CSSPropertyStrokeWidth, |
320 | CSSPropertyTabSize, |
321 | CSSPropertyTableLayout, |
322 | CSSPropertyTextAlign, |
323 | CSSPropertyTextAnchor, |
324 | CSSPropertyTextDecoration, |
325 | CSSPropertyTextDecorationColor, |
326 | CSSPropertyTextDecorationLine, |
327 | CSSPropertyTextDecorationSkip, |
328 | CSSPropertyTextDecorationStyle, |
329 | CSSPropertyTextIndent, |
330 | CSSPropertyTextOverflow, |
331 | CSSPropertyTextRendering, |
332 | CSSPropertyTextShadow, |
333 | CSSPropertyTextTransform, |
334 | CSSPropertyTextUnderlinePosition, |
335 | CSSPropertyTop, |
336 | #if ENABLE(POINTER_EVENTS) |
337 | CSSPropertyTouchAction, |
338 | #endif |
339 | CSSPropertyTransform, |
340 | CSSPropertyTransformBox, |
341 | CSSPropertyTransformOrigin, |
342 | CSSPropertyTransformStyle, |
343 | CSSPropertyTransitionDelay, |
344 | CSSPropertyTransitionDuration, |
345 | CSSPropertyTransitionProperty, |
346 | CSSPropertyTransitionTimingFunction, |
347 | CSSPropertyUnicodeBidi, |
348 | CSSPropertyVectorEffect, |
349 | CSSPropertyVerticalAlign, |
350 | CSSPropertyVisibility, |
351 | CSSPropertyWhiteSpace, |
352 | CSSPropertyWidows, |
353 | CSSPropertyWidth, |
354 | CSSPropertyWillChange, |
355 | CSSPropertyWordBreak, |
356 | CSSPropertyWordSpacing, |
357 | CSSPropertyWordWrap, |
358 | CSSPropertyWritingMode, |
359 | CSSPropertyX, |
360 | CSSPropertyY, |
361 | CSSPropertyZIndex, |
362 | CSSPropertyZoom, |
363 | CSSPropertyAppleColorFilter, |
364 | CSSPropertyWebkitAppearance, |
365 | #if ENABLE(FILTERS_LEVEL_2) |
366 | CSSPropertyWebkitBackdropFilter, |
367 | #endif |
368 | CSSPropertyWebkitBackfaceVisibility, |
369 | CSSPropertyWebkitBackgroundClip, |
370 | CSSPropertyWebkitBackgroundComposite, |
371 | CSSPropertyWebkitBackgroundOrigin, |
372 | CSSPropertyWebkitBackgroundSize, |
373 | CSSPropertyWebkitBorderFit, |
374 | CSSPropertyWebkitBorderHorizontalSpacing, |
375 | CSSPropertyWebkitBorderImage, |
376 | CSSPropertyWebkitBorderVerticalSpacing, |
377 | CSSPropertyWebkitBoxAlign, |
378 | #if ENABLE(CSS_BOX_DECORATION_BREAK) |
379 | CSSPropertyWebkitBoxDecorationBreak, |
380 | #endif |
381 | CSSPropertyWebkitBoxDirection, |
382 | CSSPropertyWebkitBoxFlex, |
383 | CSSPropertyWebkitBoxFlexGroup, |
384 | CSSPropertyWebkitBoxLines, |
385 | CSSPropertyWebkitBoxOrdinalGroup, |
386 | CSSPropertyWebkitBoxOrient, |
387 | CSSPropertyWebkitBoxPack, |
388 | CSSPropertyWebkitBoxReflect, |
389 | CSSPropertyWebkitBoxShadow, |
390 | CSSPropertyWebkitClipPath, |
391 | CSSPropertyWebkitColumnAxis, |
392 | CSSPropertyWebkitColumnBreakAfter, |
393 | CSSPropertyWebkitColumnBreakBefore, |
394 | CSSPropertyWebkitColumnBreakInside, |
395 | CSSPropertyWebkitColumnProgression, |
396 | #if ENABLE(CURSOR_VISIBILITY) |
397 | CSSPropertyWebkitCursorVisibility, |
398 | #endif |
399 | CSSPropertyWebkitFontKerning, |
400 | CSSPropertyWebkitFontSmoothing, |
401 | CSSPropertyWebkitHyphenateCharacter, |
402 | CSSPropertyWebkitHyphenateLimitAfter, |
403 | CSSPropertyWebkitHyphenateLimitBefore, |
404 | CSSPropertyWebkitHyphenateLimitLines, |
405 | CSSPropertyWebkitHyphens, |
406 | CSSPropertyWebkitInitialLetter, |
407 | CSSPropertyWebkitLineAlign, |
408 | CSSPropertyWebkitLineBoxContain, |
409 | CSSPropertyWebkitLineClamp, |
410 | CSSPropertyWebkitLineGrid, |
411 | CSSPropertyWebkitLineSnap, |
412 | CSSPropertyWebkitLocale, |
413 | CSSPropertyWebkitMarginAfterCollapse, |
414 | CSSPropertyWebkitMarginBeforeCollapse, |
415 | CSSPropertyWebkitMarqueeDirection, |
416 | CSSPropertyWebkitMarqueeIncrement, |
417 | CSSPropertyWebkitMarqueeRepetition, |
418 | CSSPropertyWebkitMarqueeStyle, |
419 | CSSPropertyWebkitMaskBoxImage, |
420 | CSSPropertyWebkitMaskBoxImageOutset, |
421 | CSSPropertyWebkitMaskBoxImageRepeat, |
422 | CSSPropertyWebkitMaskBoxImageSlice, |
423 | CSSPropertyWebkitMaskBoxImageSource, |
424 | CSSPropertyWebkitMaskBoxImageWidth, |
425 | CSSPropertyWebkitMaskClip, |
426 | CSSPropertyWebkitMaskComposite, |
427 | CSSPropertyWebkitMaskImage, |
428 | CSSPropertyWebkitMaskOrigin, |
429 | CSSPropertyWebkitMaskPosition, |
430 | CSSPropertyWebkitMaskRepeat, |
431 | CSSPropertyWebkitMaskSize, |
432 | CSSPropertyWebkitMaskSourceType, |
433 | CSSPropertyWebkitNbspMode, |
434 | #if ENABLE(OVERFLOW_SCROLLING_TOUCH) |
435 | CSSPropertyWebkitOverflowScrolling, |
436 | #endif |
437 | CSSPropertyWebkitPrintColorAdjust, |
438 | CSSPropertyWebkitRtlOrdering, |
439 | #if ENABLE(TOUCH_EVENTS) |
440 | CSSPropertyWebkitTapHighlightColor, |
441 | #endif |
442 | #if ENABLE(CSS3_TEXT) |
443 | CSSPropertyWebkitTextAlignLast, |
444 | #endif |
445 | CSSPropertyWebkitTextCombine, |
446 | CSSPropertyWebkitTextDecorationsInEffect, |
447 | CSSPropertyWebkitTextEmphasisColor, |
448 | CSSPropertyWebkitTextEmphasisPosition, |
449 | CSSPropertyWebkitTextEmphasisStyle, |
450 | CSSPropertyWebkitTextFillColor, |
451 | #if ENABLE(CSS3_TEXT) |
452 | CSSPropertyWebkitTextJustify, |
453 | #endif |
454 | CSSPropertyWebkitTextOrientation, |
455 | CSSPropertyWebkitTextSecurity, |
456 | #if ENABLE(TEXT_AUTOSIZING) |
457 | CSSPropertyWebkitTextSizeAdjust, |
458 | #endif |
459 | CSSPropertyWebkitTextStrokeColor, |
460 | CSSPropertyWebkitTextStrokeWidth, |
461 | CSSPropertyWebkitTextZoom, |
462 | #if PLATFORM(IOS_FAMILY) |
463 | CSSPropertyWebkitTouchCallout, |
464 | #endif |
465 | CSSPropertyWebkitTransformStyle, |
466 | CSSPropertyWebkitUserDrag, |
467 | CSSPropertyWebkitUserModify, |
468 | CSSPropertyWebkitUserSelect, |
469 | }; |
470 | |
471 | const unsigned numComputedProperties = WTF_ARRAY_LENGTH(computedProperties); |
472 | |
473 | static CSSValueID valueForRepeatRule(int rule) |
474 | { |
475 | switch (rule) { |
476 | case RepeatImageRule: |
477 | return CSSValueRepeat; |
478 | case RoundImageRule: |
479 | return CSSValueRound; |
480 | case SpaceImageRule: |
481 | return CSSValueSpace; |
482 | default: |
483 | return CSSValueStretch; |
484 | } |
485 | } |
486 | |
487 | static Ref<CSSPrimitiveValue> valueForImageSliceSide(const Length& length) |
488 | { |
489 | // These values can be percentages, numbers, or while an animation of mixed types is in progress, |
490 | // a calculation that combines a percentage and a number. |
491 | if (length.isPercent()) |
492 | return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE); |
493 | if (length.isFixed()) |
494 | return CSSValuePool::singleton().createValue(length.value(), CSSPrimitiveValue::CSS_NUMBER); |
495 | |
496 | // Calculating the actual length currently in use would require most of the code from RenderBoxModelObject::paintNinePieceImage. |
497 | // And even if we could do that, it's not clear if that's exactly what we'd want during animation. |
498 | // FIXME: For now, just return 0. |
499 | ASSERT(length.isCalculated()); |
500 | return CSSValuePool::singleton().createValue(0, CSSPrimitiveValue::CSS_NUMBER); |
501 | } |
502 | |
503 | static Ref<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image) |
504 | { |
505 | auto& slices = image.imageSlices(); |
506 | |
507 | RefPtr<CSSPrimitiveValue> top = valueForImageSliceSide(slices.top()); |
508 | |
509 | RefPtr<CSSPrimitiveValue> right; |
510 | RefPtr<CSSPrimitiveValue> bottom; |
511 | RefPtr<CSSPrimitiveValue> left; |
512 | |
513 | if (slices.right() == slices.top() && slices.bottom() == slices.top() && slices.left() == slices.top()) { |
514 | right = top; |
515 | bottom = top; |
516 | left = top; |
517 | } else { |
518 | right = valueForImageSliceSide(slices.right()); |
519 | |
520 | if (slices.bottom() == slices.top() && slices.right() == slices.left()) { |
521 | bottom = top; |
522 | left = right; |
523 | } else { |
524 | bottom = valueForImageSliceSide(slices.bottom()); |
525 | |
526 | if (slices.left() == slices.right()) |
527 | left = right; |
528 | else |
529 | left = valueForImageSliceSide(slices.left()); |
530 | } |
531 | } |
532 | |
533 | auto quad = Quad::create(); |
534 | quad->setTop(WTFMove(top)); |
535 | quad->setRight(WTFMove(right)); |
536 | quad->setBottom(WTFMove(bottom)); |
537 | quad->setLeft(WTFMove(left)); |
538 | |
539 | return CSSBorderImageSliceValue::create(CSSValuePool::singleton().createValue(WTFMove(quad)), image.fill()); |
540 | } |
541 | |
542 | static Ref<CSSPrimitiveValue> valueForNinePieceImageQuad(const LengthBox& box) |
543 | { |
544 | RefPtr<CSSPrimitiveValue> top; |
545 | RefPtr<CSSPrimitiveValue> right; |
546 | RefPtr<CSSPrimitiveValue> bottom; |
547 | RefPtr<CSSPrimitiveValue> left; |
548 | |
549 | auto& cssValuePool = CSSValuePool::singleton(); |
550 | |
551 | if (box.top().isRelative()) |
552 | top = cssValuePool.createValue(box.top().value(), CSSPrimitiveValue::CSS_NUMBER); |
553 | else |
554 | top = cssValuePool.createValue(box.top()); |
555 | |
556 | if (box.right() == box.top() && box.bottom() == box.top() && box.left() == box.top()) { |
557 | right = top; |
558 | bottom = top; |
559 | left = top; |
560 | } else { |
561 | if (box.right().isRelative()) |
562 | right = cssValuePool.createValue(box.right().value(), CSSPrimitiveValue::CSS_NUMBER); |
563 | else |
564 | right = cssValuePool.createValue(box.right()); |
565 | |
566 | if (box.bottom() == box.top() && box.right() == box.left()) { |
567 | bottom = top; |
568 | left = right; |
569 | } else { |
570 | if (box.bottom().isRelative()) |
571 | bottom = cssValuePool.createValue(box.bottom().value(), CSSPrimitiveValue::CSS_NUMBER); |
572 | else |
573 | bottom = cssValuePool.createValue(box.bottom()); |
574 | |
575 | if (box.left() == box.right()) |
576 | left = right; |
577 | else { |
578 | if (box.left().isRelative()) |
579 | left = cssValuePool.createValue(box.left().value(), CSSPrimitiveValue::CSS_NUMBER); |
580 | else |
581 | left = cssValuePool.createValue(box.left()); |
582 | } |
583 | } |
584 | } |
585 | |
586 | auto quad = Quad::create(); |
587 | quad->setTop(WTFMove(top)); |
588 | quad->setRight(WTFMove(right)); |
589 | quad->setBottom(WTFMove(bottom)); |
590 | quad->setLeft(WTFMove(left)); |
591 | |
592 | return cssValuePool.createValue(WTFMove(quad)); |
593 | } |
594 | |
595 | static Ref<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image) |
596 | { |
597 | auto& cssValuePool = CSSValuePool::singleton(); |
598 | auto horizontalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.horizontalRule())); |
599 | RefPtr<CSSPrimitiveValue> verticalRepeat; |
600 | if (image.horizontalRule() == image.verticalRule()) |
601 | verticalRepeat = horizontalRepeat.copyRef(); |
602 | else |
603 | verticalRepeat = cssValuePool.createIdentifierValue(valueForRepeatRule(image.verticalRule())); |
604 | return cssValuePool.createValue(Pair::create(WTFMove(horizontalRepeat), WTFMove(verticalRepeat))); |
605 | } |
606 | |
607 | static Ref<CSSValue> valueForNinePieceImage(const NinePieceImage& image) |
608 | { |
609 | if (!image.hasImage()) |
610 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
611 | |
612 | // Image first. |
613 | RefPtr<CSSValue> imageValue; |
614 | if (image.image()) |
615 | imageValue = image.image()->cssValue(); |
616 | |
617 | // Create the image slice. |
618 | RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image); |
619 | |
620 | // Create the border area slices. |
621 | RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices()); |
622 | |
623 | // Create the border outset. |
624 | RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset()); |
625 | |
626 | // Create the repeat rules. |
627 | RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image); |
628 | |
629 | return createBorderImageValue(WTFMove(imageValue), WTFMove(imageSlices), WTFMove(borderSlices), WTFMove(outset), WTFMove(repeat)); |
630 | } |
631 | |
632 | inline static Ref<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style) |
633 | { |
634 | return CSSValuePool::singleton().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX); |
635 | } |
636 | |
637 | inline static Ref<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style) |
638 | { |
639 | return CSSValuePool::singleton().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER); |
640 | } |
641 | |
642 | static Ref<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style) |
643 | { |
644 | if (length.isFixed()) |
645 | return zoomAdjustedPixelValue(length.value(), style); |
646 | return CSSValuePool::singleton().createValue(length, style); |
647 | } |
648 | |
649 | static Ref<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style) |
650 | { |
651 | if (!reflection) |
652 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
653 | |
654 | RefPtr<CSSPrimitiveValue> offset; |
655 | if (reflection->offset().isPercentOrCalculated()) |
656 | offset = CSSValuePool::singleton().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE); |
657 | else |
658 | offset = zoomAdjustedPixelValue(reflection->offset().value(), style); |
659 | |
660 | RefPtr<CSSPrimitiveValue> direction; |
661 | switch (reflection->direction()) { |
662 | case ReflectionBelow: |
663 | direction = CSSValuePool::singleton().createIdentifierValue(CSSValueBelow); |
664 | break; |
665 | case ReflectionAbove: |
666 | direction = CSSValuePool::singleton().createIdentifierValue(CSSValueAbove); |
667 | break; |
668 | case ReflectionLeft: |
669 | direction = CSSValuePool::singleton().createIdentifierValue(CSSValueLeft); |
670 | break; |
671 | case ReflectionRight: |
672 | direction = CSSValuePool::singleton().createIdentifierValue(CSSValueRight); |
673 | break; |
674 | } |
675 | |
676 | return CSSReflectValue::create(direction.releaseNonNull(), offset.releaseNonNull(), valueForNinePieceImage(reflection->mask())); |
677 | } |
678 | |
679 | static Ref<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer& layer, const RenderStyle& style) |
680 | { |
681 | auto list = CSSValueList::createSpaceSeparated(); |
682 | if (layer.isBackgroundXOriginSet()) { |
683 | ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); |
684 | list->append(CSSValuePool::singleton().createValue(layer.backgroundXOrigin())); |
685 | } |
686 | list->append(zoomAdjustedPixelValueForLength(layer.xPosition(), style)); |
687 | if (layer.isBackgroundYOriginSet()) { |
688 | ASSERT(propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition); |
689 | list->append(CSSValuePool::singleton().createValue(layer.backgroundYOrigin())); |
690 | } |
691 | list->append(zoomAdjustedPixelValueForLength(layer.yPosition(), style)); |
692 | return list; |
693 | } |
694 | |
695 | static Length getOffsetComputedLength(const RenderStyle& style, CSSPropertyID propertyID) |
696 | { |
697 | // If specified as a length, the corresponding absolute length; if specified as |
698 | // a percentage, the specified value; otherwise, 'auto'. Hence, we can just |
699 | // return the value in the style. |
700 | // |
701 | // See http://www.w3.org/TR/CSS21/cascade.html#computed-value |
702 | switch (propertyID) { |
703 | case CSSPropertyLeft: |
704 | return style.left(); |
705 | case CSSPropertyRight: |
706 | return style.right(); |
707 | case CSSPropertyTop: |
708 | return style.top(); |
709 | case CSSPropertyBottom: |
710 | return style.bottom(); |
711 | default: |
712 | ASSERT_NOT_REACHED(); |
713 | } |
714 | |
715 | return { }; |
716 | } |
717 | |
718 | static LayoutUnit getOffsetUsedStyleRelative(RenderBox& box, CSSPropertyID propertyID) |
719 | { |
720 | // For relatively positioned boxes, the offset is with respect to the top edges |
721 | // of the box itself. This ties together top/bottom and left/right to be |
722 | // opposites of each other. |
723 | // |
724 | // See http://www.w3.org/TR/CSS2/visuren.html#relative-positioning |
725 | // |
726 | // Specifically; |
727 | // Since boxes are not split or stretched as a result of 'left' or |
728 | // 'right', the used values are always: left = -right. |
729 | // and |
730 | // Since boxes are not split or stretched as a result of 'top' or |
731 | // 'bottom', the used values are always: top = -bottom. |
732 | switch (propertyID) { |
733 | case CSSPropertyTop: |
734 | return box.relativePositionOffset().height(); |
735 | case CSSPropertyBottom: |
736 | return -(box.relativePositionOffset().height()); |
737 | case CSSPropertyLeft: |
738 | return box.relativePositionOffset().width(); |
739 | case CSSPropertyRight: |
740 | return -(box.relativePositionOffset().width()); |
741 | default: |
742 | ASSERT_NOT_REACHED(); |
743 | } |
744 | |
745 | return 0; |
746 | } |
747 | |
748 | static LayoutUnit getOffsetUsedStyleOutOfFlowPositioned(RenderBlock& container, RenderBox& box, CSSPropertyID propertyID) |
749 | { |
750 | // For out-of-flow positioned boxes, the offset is how far an box's margin |
751 | // edge is offset below the edge of the box's containing block. |
752 | // See http://www.w3.org/TR/CSS2/visuren.html#position-props |
753 | |
754 | // Margins are included in offsetTop/offsetLeft so we need to remove them here. |
755 | switch (propertyID) { |
756 | case CSSPropertyTop: |
757 | return box.offsetTop() - box.marginTop(); |
758 | case CSSPropertyBottom: |
759 | return container.clientHeight() - (box.offsetTop() + box.offsetHeight()) - box.marginBottom(); |
760 | case CSSPropertyLeft: |
761 | return box.offsetLeft() - box.marginLeft(); |
762 | case CSSPropertyRight: |
763 | return container.clientWidth() - (box.offsetLeft() + box.offsetWidth()) - box.marginRight(); |
764 | default: |
765 | ASSERT_NOT_REACHED(); |
766 | } |
767 | |
768 | return 0; |
769 | } |
770 | |
771 | static RefPtr<CSSValue> positionOffsetValue(const RenderStyle& style, CSSPropertyID propertyID, RenderObject* renderer) |
772 | { |
773 | auto offset = getOffsetComputedLength(style, propertyID); |
774 | |
775 | // If the element is not displayed; return the "computed value". |
776 | if (!renderer || !renderer->isBox()) |
777 | return zoomAdjustedPixelValueForLength(offset, style); |
778 | |
779 | auto& box = downcast<RenderBox>(*renderer); |
780 | auto* containingBlock = box.containingBlock(); |
781 | |
782 | // Resolve a "computed value" percentage if the element is positioned. |
783 | if (containingBlock && offset.isPercentOrCalculated() && box.isPositioned()) { |
784 | bool isVerticalProperty; |
785 | if (propertyID == CSSPropertyTop || propertyID == CSSPropertyBottom) |
786 | isVerticalProperty = true; |
787 | else { |
788 | ASSERT(propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight); |
789 | isVerticalProperty = false; |
790 | } |
791 | LayoutUnit containingBlockSize; |
792 | if (box.isStickilyPositioned()) { |
793 | const RenderBox& enclosingScrollportBox = |
794 | box.enclosingScrollportBox(); |
795 | if (isVerticalProperty == enclosingScrollportBox.isHorizontalWritingMode()) |
796 | containingBlockSize = enclosingScrollportBox.contentLogicalHeight(); |
797 | else |
798 | containingBlockSize = enclosingScrollportBox.contentLogicalWidth(); |
799 | } else { |
800 | if (isVerticalProperty == containingBlock->isHorizontalWritingMode()) { |
801 | containingBlockSize = box.isOutOfFlowPositioned() |
802 | ? box.containingBlockLogicalHeightForPositioned(*containingBlock, false) |
803 | : box.containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding); |
804 | } else { |
805 | containingBlockSize = box.isOutOfFlowPositioned() |
806 | ? box.containingBlockLogicalWidthForPositioned(*containingBlock, nullptr, false) |
807 | : box.containingBlockLogicalWidthForContent(); |
808 | } |
809 | } |
810 | return zoomAdjustedPixelValue(floatValueForLength(offset, containingBlockSize), style); |
811 | } |
812 | |
813 | // Return a "computed value" length. |
814 | if (!offset.isAuto()) |
815 | return zoomAdjustedPixelValueForLength(offset, style); |
816 | |
817 | // The property won't be overconstrained if its computed value is "auto", so the "used value" can be returned. |
818 | if (box.isRelativelyPositioned()) |
819 | return zoomAdjustedPixelValue(getOffsetUsedStyleRelative(box, propertyID), style); |
820 | |
821 | if (containingBlock && box.isOutOfFlowPositioned()) |
822 | return zoomAdjustedPixelValue(getOffsetUsedStyleOutOfFlowPositioned(*containingBlock, box, propertyID), style); |
823 | |
824 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
825 | } |
826 | |
827 | Ref<CSSPrimitiveValue> ComputedStyleExtractor::(const RenderStyle* style, const Color& color) const |
828 | { |
829 | // This function does NOT look at visited information, so that computed style doesn't expose that. |
830 | if (!color.isValid()) |
831 | return CSSValuePool::singleton().createColorValue(style->color()); |
832 | return CSSValuePool::singleton().createColorValue(color); |
833 | } |
834 | |
835 | static Ref<CSSPrimitiveValue> percentageOrZoomAdjustedValue(Length length, const RenderStyle& style) |
836 | { |
837 | if (length.isPercent()) |
838 | return CSSValuePool::singleton().createValue(length.percent(), CSSPrimitiveValue::CSS_PERCENTAGE); |
839 | |
840 | return zoomAdjustedPixelValue(valueForLength(length, 0), style); |
841 | } |
842 | |
843 | static Ref<CSSPrimitiveValue> autoOrZoomAdjustedValue(Length length, const RenderStyle& style) |
844 | { |
845 | if (length.isAuto()) |
846 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
847 | |
848 | return zoomAdjustedPixelValue(valueForLength(length, 0), style); |
849 | } |
850 | |
851 | static Ref<CSSValueList> borderRadiusCornerValues(const LengthSize& radius, const RenderStyle& style) |
852 | { |
853 | auto list = CSSValueList::createSpaceSeparated(); |
854 | list->append(percentageOrZoomAdjustedValue(radius.width, style)); |
855 | list->append(percentageOrZoomAdjustedValue(radius.height, style)); |
856 | return list; |
857 | } |
858 | |
859 | static Ref<CSSValue> borderRadiusCornerValue(const LengthSize& radius, const RenderStyle& style) |
860 | { |
861 | if (radius.width == radius.height) |
862 | return percentageOrZoomAdjustedValue(radius.width, style); |
863 | return borderRadiusCornerValues(radius, style); |
864 | } |
865 | |
866 | static Ref<CSSValueList> borderRadiusShorthandValue(const RenderStyle& style) |
867 | { |
868 | auto list = CSSValueList::createSlashSeparated(); |
869 | bool showHorizontalBottomLeft = style.borderTopRightRadius().width != style.borderBottomLeftRadius().width; |
870 | bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width != style.borderTopLeftRadius().width); |
871 | bool showHorizontalTopRight = showHorizontalBottomRight || (style.borderTopRightRadius().width != style.borderTopLeftRadius().width); |
872 | |
873 | bool showVerticalBottomLeft = style.borderTopRightRadius().height != style.borderBottomLeftRadius().height; |
874 | bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height != style.borderTopLeftRadius().height); |
875 | bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height != style.borderTopLeftRadius().height); |
876 | |
877 | auto topLeftRadius = borderRadiusCornerValues(style.borderTopLeftRadius(), style); |
878 | auto topRightRadius = borderRadiusCornerValues(style.borderTopRightRadius(), style); |
879 | auto bottomRightRadius = borderRadiusCornerValues(style.borderBottomRightRadius(), style); |
880 | auto bottomLeftRadius = borderRadiusCornerValues(style.borderBottomLeftRadius(), style); |
881 | |
882 | auto horizontalRadii = CSSValueList::createSpaceSeparated(); |
883 | horizontalRadii->append(*topLeftRadius->item(0)); |
884 | if (showHorizontalTopRight) |
885 | horizontalRadii->append(*topRightRadius->item(0)); |
886 | if (showHorizontalBottomRight) |
887 | horizontalRadii->append(*bottomRightRadius->item(0)); |
888 | if (showHorizontalBottomLeft) |
889 | horizontalRadii->append(*bottomLeftRadius->item(0)); |
890 | |
891 | list->append(WTFMove(horizontalRadii)); |
892 | |
893 | auto verticalRadiiList = CSSValueList::createSpaceSeparated(); |
894 | verticalRadiiList->append(*topLeftRadius->item(1)); |
895 | if (showVerticalTopRight) |
896 | verticalRadiiList->append(*topRightRadius->item(1)); |
897 | if (showVerticalBottomRight) |
898 | verticalRadiiList->append(*bottomRightRadius->item(1)); |
899 | if (showVerticalBottomLeft) |
900 | verticalRadiiList->append(*bottomLeftRadius->item(1)); |
901 | |
902 | if (!verticalRadiiList->equals(downcast<CSSValueList>(*list->item(0)))) |
903 | list->append(WTFMove(verticalRadiiList)); |
904 | |
905 | return list; |
906 | } |
907 | |
908 | static LayoutRect sizingBox(RenderObject& renderer) |
909 | { |
910 | if (!is<RenderBox>(renderer)) |
911 | return LayoutRect(); |
912 | |
913 | auto& box = downcast<RenderBox>(renderer); |
914 | return box.style().boxSizing() == BoxSizing::BorderBox ? box.borderBoxRect() : box.computedCSSContentBoxRect(); |
915 | } |
916 | |
917 | static Ref<CSSFunctionValue> matrixTransformValue(const TransformationMatrix& transform, const RenderStyle& style) |
918 | { |
919 | RefPtr<CSSFunctionValue> transformValue; |
920 | auto& cssValuePool = CSSValuePool::singleton(); |
921 | if (transform.isAffine()) { |
922 | transformValue = CSSFunctionValue::create(CSSValueMatrix); |
923 | |
924 | transformValue->append(cssValuePool.createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER)); |
925 | transformValue->append(cssValuePool.createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER)); |
926 | transformValue->append(cssValuePool.createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER)); |
927 | transformValue->append(cssValuePool.createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER)); |
928 | transformValue->append(zoomAdjustedNumberValue(transform.e(), style)); |
929 | transformValue->append(zoomAdjustedNumberValue(transform.f(), style)); |
930 | } else { |
931 | transformValue = CSSFunctionValue::create(CSSValueMatrix3d); |
932 | |
933 | transformValue->append(cssValuePool.createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER)); |
934 | transformValue->append(cssValuePool.createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER)); |
935 | transformValue->append(cssValuePool.createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER)); |
936 | transformValue->append(cssValuePool.createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER)); |
937 | |
938 | transformValue->append(cssValuePool.createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER)); |
939 | transformValue->append(cssValuePool.createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER)); |
940 | transformValue->append(cssValuePool.createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER)); |
941 | transformValue->append(cssValuePool.createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER)); |
942 | |
943 | transformValue->append(cssValuePool.createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER)); |
944 | transformValue->append(cssValuePool.createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER)); |
945 | transformValue->append(cssValuePool.createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER)); |
946 | transformValue->append(cssValuePool.createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER)); |
947 | |
948 | transformValue->append(zoomAdjustedNumberValue(transform.m41(), style)); |
949 | transformValue->append(zoomAdjustedNumberValue(transform.m42(), style)); |
950 | transformValue->append(zoomAdjustedNumberValue(transform.m43(), style)); |
951 | transformValue->append(cssValuePool.createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER)); |
952 | } |
953 | |
954 | return transformValue.releaseNonNull(); |
955 | } |
956 | |
957 | static Ref<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style) |
958 | { |
959 | // Inline renderers do not support transforms. |
960 | if (!renderer || is<RenderInline>(*renderer) || !style.hasTransform()) |
961 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
962 | |
963 | FloatRect pixelSnappedRect; |
964 | if (is<RenderBox>(*renderer)) |
965 | pixelSnappedRect = snapRectToDevicePixels(downcast<RenderBox>(*renderer).borderBoxRect(), renderer->document().deviceScaleFactor()); |
966 | |
967 | TransformationMatrix transform; |
968 | style.applyTransform(transform, pixelSnappedRect, RenderStyle::ExcludeTransformOrigin); |
969 | // Note that this does not flatten to an affine transform if ENABLE(3D_TRANSFORMS) is off, by design. |
970 | |
971 | // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924) |
972 | auto list = CSSValueList::createSpaceSeparated(); |
973 | list->append(matrixTransformValue(transform, style)); |
974 | return list; |
975 | } |
976 | |
977 | static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(double length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) |
978 | { |
979 | return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length, style) : CSSValuePool::singleton().createValue(length, CSSPrimitiveValue::CSS_PX); |
980 | } |
981 | |
982 | static inline Ref<CSSPrimitiveValue> adjustLengthForZoom(const Length& length, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) |
983 | { |
984 | return adjust == AdjustPixelValues ? zoomAdjustedPixelValue(length.value(), style) : CSSValuePool::singleton().createValue(length); |
985 | } |
986 | |
987 | Ref<CSSValue> ComputedStyleExtractor::valueForShadow(const ShadowData* shadow, CSSPropertyID propertyID, const RenderStyle& style, AdjustPixelValuesForComputedStyle adjust) |
988 | { |
989 | auto& cssValuePool = CSSValuePool::singleton(); |
990 | if (!shadow) |
991 | return cssValuePool.createIdentifierValue(CSSValueNone); |
992 | |
993 | auto list = CSSValueList::createCommaSeparated(); |
994 | for (const ShadowData* currShadowData = shadow; currShadowData; currShadowData = currShadowData->next()) { |
995 | auto x = adjustLengthForZoom(currShadowData->x(), style, adjust); |
996 | auto y = adjustLengthForZoom(currShadowData->y(), style, adjust); |
997 | auto blur = adjustLengthForZoom(currShadowData->radius(), style, adjust); |
998 | auto spread = propertyID == CSSPropertyTextShadow ? RefPtr<CSSPrimitiveValue>() : adjustLengthForZoom(currShadowData->spread(), style, adjust); |
999 | auto style = propertyID == CSSPropertyTextShadow || currShadowData->style() == Normal ? RefPtr<CSSPrimitiveValue>() : cssValuePool.createIdentifierValue(CSSValueInset); |
1000 | auto color = cssValuePool.createColorValue(currShadowData->color()); |
1001 | list->prepend(CSSShadowValue::create(WTFMove(x), WTFMove(y), WTFMove(blur), WTFMove(spread), WTFMove(style), WTFMove(color))); |
1002 | } |
1003 | return list; |
1004 | } |
1005 | |
1006 | Ref<CSSValue> ComputedStyleExtractor::(const RenderStyle& style, const FilterOperations& filterOperations, AdjustPixelValuesForComputedStyle adjust) |
1007 | { |
1008 | auto& cssValuePool = CSSValuePool::singleton(); |
1009 | if (filterOperations.operations().isEmpty()) |
1010 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1011 | |
1012 | auto list = CSSValueList::createSpaceSeparated(); |
1013 | |
1014 | Vector<RefPtr<FilterOperation>>::const_iterator end = filterOperations.operations().end(); |
1015 | for (Vector<RefPtr<FilterOperation>>::const_iterator it = filterOperations.operations().begin(); it != end; ++it) { |
1016 | FilterOperation& filterOperation = **it; |
1017 | |
1018 | if (filterOperation.type() == FilterOperation::REFERENCE) { |
1019 | ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation); |
1020 | list->append(cssValuePool.createValue(referenceOperation.url(), CSSPrimitiveValue::CSS_URI)); |
1021 | } else { |
1022 | RefPtr<CSSFunctionValue> filterValue; |
1023 | switch (filterOperation.type()) { |
1024 | case FilterOperation::GRAYSCALE: { |
1025 | filterValue = CSSFunctionValue::create(CSSValueGrayscale); |
1026 | filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1027 | break; |
1028 | } |
1029 | case FilterOperation::SEPIA: { |
1030 | filterValue = CSSFunctionValue::create(CSSValueSepia); |
1031 | filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1032 | break; |
1033 | } |
1034 | case FilterOperation::SATURATE: { |
1035 | filterValue = CSSFunctionValue::create(CSSValueSaturate); |
1036 | filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1037 | break; |
1038 | } |
1039 | case FilterOperation::HUE_ROTATE: { |
1040 | filterValue = CSSFunctionValue::create(CSSValueHueRotate); |
1041 | filterValue->append(cssValuePool.createValue(downcast<BasicColorMatrixFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_DEG)); |
1042 | break; |
1043 | } |
1044 | case FilterOperation::INVERT: { |
1045 | filterValue = CSSFunctionValue::create(CSSValueInvert); |
1046 | filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1047 | break; |
1048 | } |
1049 | case FilterOperation::APPLE_INVERT_LIGHTNESS: { |
1050 | filterValue = CSSFunctionValue::create(CSSValueAppleInvertLightness); |
1051 | break; |
1052 | } |
1053 | case FilterOperation::OPACITY: { |
1054 | filterValue = CSSFunctionValue::create(CSSValueOpacity); |
1055 | filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1056 | break; |
1057 | } |
1058 | case FilterOperation::BRIGHTNESS: { |
1059 | filterValue = CSSFunctionValue::create(CSSValueBrightness); |
1060 | filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1061 | break; |
1062 | } |
1063 | case FilterOperation::CONTRAST: { |
1064 | filterValue = CSSFunctionValue::create(CSSValueContrast); |
1065 | filterValue->append(cssValuePool.createValue(downcast<BasicComponentTransferFilterOperation>(filterOperation).amount(), CSSPrimitiveValue::CSS_NUMBER)); |
1066 | break; |
1067 | } |
1068 | case FilterOperation::BLUR: { |
1069 | filterValue = CSSFunctionValue::create(CSSValueBlur); |
1070 | filterValue->append(adjustLengthForZoom(downcast<BlurFilterOperation>(filterOperation).stdDeviation(), style, adjust)); |
1071 | break; |
1072 | } |
1073 | case FilterOperation::DROP_SHADOW: { |
1074 | DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation); |
1075 | filterValue = CSSFunctionValue::create(CSSValueDropShadow); |
1076 | // We want our computed style to look like that of a text shadow (has neither spread nor inset style). |
1077 | ShadowData shadowData = ShadowData(dropShadowOperation.location(), dropShadowOperation.stdDeviation(), 0, Normal, false, dropShadowOperation.color()); |
1078 | filterValue->append(valueForShadow(&shadowData, CSSPropertyTextShadow, style, adjust)); |
1079 | break; |
1080 | } |
1081 | default: |
1082 | ASSERT_NOT_REACHED(); |
1083 | filterValue = CSSFunctionValue::create(CSSValueInvalid); |
1084 | break; |
1085 | } |
1086 | list->append(filterValue.releaseNonNull()); |
1087 | } |
1088 | } |
1089 | return list; |
1090 | } |
1091 | |
1092 | static Ref<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style) |
1093 | { |
1094 | if (!trackBreadth.isLength()) |
1095 | return CSSValuePool::singleton().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR); |
1096 | |
1097 | const Length& trackBreadthLength = trackBreadth.length(); |
1098 | if (trackBreadthLength.isAuto()) |
1099 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
1100 | return zoomAdjustedPixelValueForLength(trackBreadthLength, style); |
1101 | } |
1102 | |
1103 | static Ref<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style) |
1104 | { |
1105 | switch (trackSize.type()) { |
1106 | case LengthTrackSizing: |
1107 | return specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style); |
1108 | case FitContentTrackSizing: { |
1109 | auto fitContentTrackSize = CSSFunctionValue::create(CSSValueFitContent); |
1110 | fitContentTrackSize->append(zoomAdjustedPixelValueForLength(trackSize.fitContentTrackBreadth().length(), style)); |
1111 | return fitContentTrackSize; |
1112 | } |
1113 | default: |
1114 | ASSERT(trackSize.type() == MinMaxTrackSizing); |
1115 | if (trackSize.minTrackBreadth().isAuto() && trackSize.maxTrackBreadth().isFlex()) |
1116 | return CSSValuePool::singleton().createValue(trackSize.maxTrackBreadth().flex(), CSSPrimitiveValue::CSS_FR); |
1117 | |
1118 | auto minMaxTrackBreadths = CSSFunctionValue::create(CSSValueMinmax); |
1119 | minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style)); |
1120 | minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style)); |
1121 | return minMaxTrackBreadths; |
1122 | } |
1123 | } |
1124 | |
1125 | class OrderedNamedLinesCollector { |
1126 | WTF_MAKE_NONCOPYABLE(OrderedNamedLinesCollector); |
1127 | public: |
1128 | OrderedNamedLinesCollector(const RenderStyle& style, bool isRowAxis, unsigned autoRepeatTracksCount) |
1129 | : m_orderedNamedGridLines(isRowAxis ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines()) |
1130 | , m_orderedNamedAutoRepeatGridLines(isRowAxis ? style.autoRepeatOrderedNamedGridColumnLines() : style.autoRepeatOrderedNamedGridRowLines()) |
1131 | , m_insertionPoint(isRowAxis ? style.gridAutoRepeatColumnsInsertionPoint() : style.gridAutoRepeatRowsInsertionPoint()) |
1132 | , m_autoRepeatTotalTracks(autoRepeatTracksCount) |
1133 | , m_autoRepeatTrackListLength(isRowAxis ? style.gridAutoRepeatColumns().size() : style.gridAutoRepeatRows().size()) |
1134 | { |
1135 | } |
1136 | |
1137 | bool isEmpty() const { return m_orderedNamedGridLines.isEmpty() && m_orderedNamedAutoRepeatGridLines.isEmpty(); } |
1138 | void collectLineNamesForIndex(CSSGridLineNamesValue&, unsigned index) const; |
1139 | |
1140 | private: |
1141 | |
1142 | enum NamedLinesType { NamedLines, AutoRepeatNamedLines }; |
1143 | void appendLines(CSSGridLineNamesValue&, unsigned index, NamedLinesType) const; |
1144 | |
1145 | const OrderedNamedGridLinesMap& m_orderedNamedGridLines; |
1146 | const OrderedNamedGridLinesMap& m_orderedNamedAutoRepeatGridLines; |
1147 | unsigned m_insertionPoint; |
1148 | unsigned m_autoRepeatTotalTracks; |
1149 | unsigned m_autoRepeatTrackListLength; |
1150 | }; |
1151 | |
1152 | void OrderedNamedLinesCollector::appendLines(CSSGridLineNamesValue& lineNamesValue, unsigned index, NamedLinesType type) const |
1153 | { |
1154 | auto iter = type == NamedLines ? m_orderedNamedGridLines.find(index) : m_orderedNamedAutoRepeatGridLines.find(index); |
1155 | auto endIter = type == NamedLines ? m_orderedNamedGridLines.end() : m_orderedNamedAutoRepeatGridLines.end(); |
1156 | if (iter == endIter) |
1157 | return; |
1158 | |
1159 | auto& cssValuePool = CSSValuePool::singleton(); |
1160 | for (const auto& lineName : iter->value) |
1161 | lineNamesValue.append(cssValuePool.createValue(lineName, CSSPrimitiveValue::CSS_STRING)); |
1162 | } |
1163 | |
1164 | void OrderedNamedLinesCollector::collectLineNamesForIndex(CSSGridLineNamesValue& lineNamesValue, unsigned i) const |
1165 | { |
1166 | ASSERT(!isEmpty()); |
1167 | if (m_orderedNamedAutoRepeatGridLines.isEmpty() || i < m_insertionPoint) { |
1168 | appendLines(lineNamesValue, i, NamedLines); |
1169 | return; |
1170 | } |
1171 | |
1172 | ASSERT(m_autoRepeatTotalTracks); |
1173 | |
1174 | if (i > m_insertionPoint + m_autoRepeatTotalTracks) { |
1175 | appendLines(lineNamesValue, i - (m_autoRepeatTotalTracks - 1), NamedLines); |
1176 | return; |
1177 | } |
1178 | |
1179 | if (i == m_insertionPoint) { |
1180 | appendLines(lineNamesValue, i, NamedLines); |
1181 | appendLines(lineNamesValue, 0, AutoRepeatNamedLines); |
1182 | return; |
1183 | } |
1184 | |
1185 | if (i == m_insertionPoint + m_autoRepeatTotalTracks) { |
1186 | appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines); |
1187 | appendLines(lineNamesValue, m_insertionPoint + 1, NamedLines); |
1188 | return; |
1189 | } |
1190 | |
1191 | unsigned autoRepeatIndexInFirstRepetition = (i - m_insertionPoint) % m_autoRepeatTrackListLength; |
1192 | if (!autoRepeatIndexInFirstRepetition && i > m_insertionPoint) |
1193 | appendLines(lineNamesValue, m_autoRepeatTrackListLength, AutoRepeatNamedLines); |
1194 | appendLines(lineNamesValue, autoRepeatIndexInFirstRepetition, AutoRepeatNamedLines); |
1195 | } |
1196 | |
1197 | static void addValuesForNamedGridLinesAtIndex(OrderedNamedLinesCollector& collector, unsigned i, CSSValueList& list) |
1198 | { |
1199 | if (collector.isEmpty()) |
1200 | return; |
1201 | |
1202 | auto lineNames = CSSGridLineNamesValue::create(); |
1203 | collector.collectLineNamesForIndex(lineNames.get(), i); |
1204 | if (lineNames->length()) |
1205 | list.append(WTFMove(lineNames)); |
1206 | } |
1207 | |
1208 | static Ref<CSSValueList> valueForGridTrackSizeList(GridTrackSizingDirection direction, const RenderStyle& style) |
1209 | { |
1210 | auto& autoTrackSizes = direction == ForColumns ? style.gridAutoColumns() : style.gridAutoRows(); |
1211 | |
1212 | auto list = CSSValueList::createSpaceSeparated(); |
1213 | for (auto& trackSize : autoTrackSizes) |
1214 | list->append(specifiedValueForGridTrackSize(trackSize, style)); |
1215 | return list; |
1216 | } |
1217 | |
1218 | static Ref<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style) |
1219 | { |
1220 | bool isRowAxis = direction == ForColumns; |
1221 | bool isRenderGrid = is<RenderGrid>(renderer); |
1222 | auto& trackSizes = isRowAxis ? style.gridColumns() : style.gridRows(); |
1223 | auto& autoRepeatTrackSizes = isRowAxis ? style.gridAutoRepeatColumns() : style.gridAutoRepeatRows(); |
1224 | |
1225 | // Handle the 'none' case. |
1226 | bool trackListIsEmpty = trackSizes.isEmpty() && autoRepeatTrackSizes.isEmpty(); |
1227 | if (isRenderGrid && trackListIsEmpty) { |
1228 | // For grids we should consider every listed track, whether implicitly or explicitly |
1229 | // created. Empty grids have a sole grid line per axis. |
1230 | auto& grid = downcast<RenderGrid>(*renderer); |
1231 | auto& positions = isRowAxis ? grid.columnPositions() : grid.rowPositions(); |
1232 | trackListIsEmpty = positions.size() == 1; |
1233 | } |
1234 | |
1235 | if (trackListIsEmpty) |
1236 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1237 | |
1238 | unsigned autoRepeatTotalTracks = isRenderGrid ? downcast<RenderGrid>(renderer)->autoRepeatCountForDirection(direction) : 0; |
1239 | OrderedNamedLinesCollector collector(style, isRowAxis, autoRepeatTotalTracks); |
1240 | auto list = CSSValueList::createSpaceSeparated(); |
1241 | unsigned insertionIndex; |
1242 | if (isRenderGrid) { |
1243 | auto computedTrackSizes = downcast<RenderGrid>(*renderer).trackSizesForComputedStyle(direction); |
1244 | unsigned numTracks = computedTrackSizes.size(); |
1245 | |
1246 | for (unsigned i = 0; i < numTracks; ++i) { |
1247 | addValuesForNamedGridLinesAtIndex(collector, i, list.get()); |
1248 | list->append(zoomAdjustedPixelValue(computedTrackSizes[i], style)); |
1249 | } |
1250 | addValuesForNamedGridLinesAtIndex(collector, numTracks + 1, list.get()); |
1251 | insertionIndex = numTracks; |
1252 | } else { |
1253 | for (unsigned i = 0; i < trackSizes.size(); ++i) { |
1254 | addValuesForNamedGridLinesAtIndex(collector, i, list.get()); |
1255 | list->append(specifiedValueForGridTrackSize(trackSizes[i], style)); |
1256 | } |
1257 | insertionIndex = trackSizes.size(); |
1258 | } |
1259 | |
1260 | // Those are the trailing <ident>* allowed in the syntax. |
1261 | addValuesForNamedGridLinesAtIndex(collector, insertionIndex, list.get()); |
1262 | return list; |
1263 | } |
1264 | |
1265 | static Ref<CSSValue> valueForGridPosition(const GridPosition& position) |
1266 | { |
1267 | auto& cssValuePool = CSSValuePool::singleton(); |
1268 | if (position.isAuto()) |
1269 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
1270 | |
1271 | if (position.isNamedGridArea()) |
1272 | return cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING); |
1273 | |
1274 | auto list = CSSValueList::createSpaceSeparated(); |
1275 | if (position.isSpan()) { |
1276 | list->append(cssValuePool.createIdentifierValue(CSSValueSpan)); |
1277 | list->append(cssValuePool.createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER)); |
1278 | } else |
1279 | list->append(cssValuePool.createValue(position.integerPosition(), CSSPrimitiveValue::CSS_NUMBER)); |
1280 | |
1281 | if (!position.namedGridLine().isNull()) |
1282 | list->append(cssValuePool.createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING)); |
1283 | return list; |
1284 | } |
1285 | |
1286 | static Ref<CSSValue> createTransitionPropertyValue(const Animation& animation) |
1287 | { |
1288 | switch (animation.animationMode()) { |
1289 | case Animation::AnimateNone: |
1290 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1291 | case Animation::AnimateAll: |
1292 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAll); |
1293 | case Animation::AnimateSingleProperty: |
1294 | return CSSValuePool::singleton().createValue(getPropertyNameString(animation.property()), CSSPrimitiveValue::CSS_STRING); |
1295 | case Animation::AnimateUnknownProperty: |
1296 | return CSSValuePool::singleton().createValue(animation.unknownProperty(), CSSPrimitiveValue::CSS_STRING); |
1297 | } |
1298 | ASSERT_NOT_REACHED(); |
1299 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1300 | } |
1301 | |
1302 | static Ref<CSSValueList> transitionPropertyValue(const AnimationList* animationList) |
1303 | { |
1304 | auto list = CSSValueList::createCommaSeparated(); |
1305 | if (animationList) { |
1306 | for (size_t i = 0; i < animationList->size(); ++i) |
1307 | list->append(createTransitionPropertyValue(animationList->animation(i))); |
1308 | } else |
1309 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAll)); |
1310 | return list; |
1311 | } |
1312 | |
1313 | #if ENABLE(CSS_SCROLL_SNAP) |
1314 | |
1315 | static Ref<CSSValueList> valueForScrollSnapType(const ScrollSnapType& type) |
1316 | { |
1317 | auto value = CSSValueList::createSpaceSeparated(); |
1318 | if (type.strictness == ScrollSnapStrictness::None) |
1319 | value->append(CSSValuePool::singleton().createValue(CSSValueNone)); |
1320 | else { |
1321 | value->append(CSSPrimitiveValue::create(type.axis)); |
1322 | value->append(CSSPrimitiveValue::create(type.strictness)); |
1323 | } |
1324 | return value; |
1325 | } |
1326 | |
1327 | static Ref<CSSValueList> valueForScrollSnapAlignment(const ScrollSnapAlign& alignment) |
1328 | { |
1329 | auto value = CSSValueList::createSpaceSeparated(); |
1330 | value->append(CSSPrimitiveValue::create(alignment.x)); |
1331 | value->append(CSSPrimitiveValue::create(alignment.y)); |
1332 | return value; |
1333 | } |
1334 | |
1335 | #endif |
1336 | |
1337 | static Ref<CSSValue> willChangePropertyValue(const WillChangeData* willChangeData) |
1338 | { |
1339 | auto& cssValuePool = CSSValuePool::singleton(); |
1340 | if (!willChangeData || !willChangeData->numFeatures()) |
1341 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
1342 | |
1343 | auto list = CSSValueList::createCommaSeparated(); |
1344 | for (size_t i = 0; i < willChangeData->numFeatures(); ++i) { |
1345 | WillChangeData::FeaturePropertyPair feature = willChangeData->featureAt(i); |
1346 | switch (feature.first) { |
1347 | case WillChangeData::ScrollPosition: |
1348 | list->append(cssValuePool.createIdentifierValue(CSSValueScrollPosition)); |
1349 | break; |
1350 | case WillChangeData::Contents: |
1351 | list->append(cssValuePool.createIdentifierValue(CSSValueContents)); |
1352 | break; |
1353 | case WillChangeData::Property: |
1354 | list->append(cssValuePool.createIdentifierValue(feature.second)); |
1355 | break; |
1356 | case WillChangeData::Invalid: |
1357 | ASSERT_NOT_REACHED(); |
1358 | break; |
1359 | } |
1360 | } |
1361 | |
1362 | return list; |
1363 | } |
1364 | |
1365 | static inline void appendLigaturesValue(CSSValueList& list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue) |
1366 | { |
1367 | switch (value) { |
1368 | case FontVariantLigatures::Normal: |
1369 | return; |
1370 | case FontVariantLigatures::No: |
1371 | list.append(CSSValuePool::singleton().createIdentifierValue(noValue)); |
1372 | return; |
1373 | case FontVariantLigatures::Yes: |
1374 | list.append(CSSValuePool::singleton().createIdentifierValue(yesValue)); |
1375 | return; |
1376 | } |
1377 | ASSERT_NOT_REACHED(); |
1378 | } |
1379 | |
1380 | static Ref<CSSValue> fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates) |
1381 | { |
1382 | auto& cssValuePool = CSSValuePool::singleton(); |
1383 | if (common == FontVariantLigatures::No && discretionary == FontVariantLigatures::No && historical == FontVariantLigatures::No && contextualAlternates == FontVariantLigatures::No) |
1384 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1385 | if (common == FontVariantLigatures::Normal && discretionary == FontVariantLigatures::Normal && historical == FontVariantLigatures::Normal && contextualAlternates == FontVariantLigatures::Normal) |
1386 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
1387 | |
1388 | auto valueList = CSSValueList::createSpaceSeparated(); |
1389 | appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures); |
1390 | appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures); |
1391 | appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures); |
1392 | appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual); |
1393 | return valueList; |
1394 | } |
1395 | |
1396 | static Ref<CSSValue> fontVariantPositionPropertyValue(FontVariantPosition position) |
1397 | { |
1398 | auto& cssValuePool = CSSValuePool::singleton(); |
1399 | CSSValueID valueID = CSSValueNormal; |
1400 | switch (position) { |
1401 | case FontVariantPosition::Normal: |
1402 | break; |
1403 | case FontVariantPosition::Subscript: |
1404 | valueID = CSSValueSub; |
1405 | break; |
1406 | case FontVariantPosition::Superscript: |
1407 | valueID = CSSValueSuper; |
1408 | break; |
1409 | } |
1410 | return cssValuePool.createIdentifierValue(valueID); |
1411 | } |
1412 | |
1413 | static Ref<CSSValue> fontVariantCapsPropertyValue(FontVariantCaps caps) |
1414 | { |
1415 | auto& cssValuePool = CSSValuePool::singleton(); |
1416 | CSSValueID valueID = CSSValueNormal; |
1417 | switch (caps) { |
1418 | case FontVariantCaps::Normal: |
1419 | break; |
1420 | case FontVariantCaps::Small: |
1421 | valueID = CSSValueSmallCaps; |
1422 | break; |
1423 | case FontVariantCaps::AllSmall: |
1424 | valueID = CSSValueAllSmallCaps; |
1425 | break; |
1426 | case FontVariantCaps::Petite: |
1427 | valueID = CSSValuePetiteCaps; |
1428 | break; |
1429 | case FontVariantCaps::AllPetite: |
1430 | valueID = CSSValueAllPetiteCaps; |
1431 | break; |
1432 | case FontVariantCaps::Unicase: |
1433 | valueID = CSSValueUnicase; |
1434 | break; |
1435 | case FontVariantCaps::Titling: |
1436 | valueID = CSSValueTitlingCaps; |
1437 | break; |
1438 | } |
1439 | return cssValuePool.createIdentifierValue(valueID); |
1440 | } |
1441 | |
1442 | static Ref<CSSValue> fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero) |
1443 | { |
1444 | auto& cssValuePool = CSSValuePool::singleton(); |
1445 | if (figure == FontVariantNumericFigure::Normal && spacing == FontVariantNumericSpacing::Normal && fraction == FontVariantNumericFraction::Normal && ordinal == FontVariantNumericOrdinal::Normal && slashedZero == FontVariantNumericSlashedZero::Normal) |
1446 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
1447 | |
1448 | auto valueList = CSSValueList::createSpaceSeparated(); |
1449 | switch (figure) { |
1450 | case FontVariantNumericFigure::Normal: |
1451 | break; |
1452 | case FontVariantNumericFigure::LiningNumbers: |
1453 | valueList->append(cssValuePool.createIdentifierValue(CSSValueLiningNums)); |
1454 | break; |
1455 | case FontVariantNumericFigure::OldStyleNumbers: |
1456 | valueList->append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums)); |
1457 | break; |
1458 | } |
1459 | |
1460 | switch (spacing) { |
1461 | case FontVariantNumericSpacing::Normal: |
1462 | break; |
1463 | case FontVariantNumericSpacing::ProportionalNumbers: |
1464 | valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalNums)); |
1465 | break; |
1466 | case FontVariantNumericSpacing::TabularNumbers: |
1467 | valueList->append(cssValuePool.createIdentifierValue(CSSValueTabularNums)); |
1468 | break; |
1469 | } |
1470 | |
1471 | switch (fraction) { |
1472 | case FontVariantNumericFraction::Normal: |
1473 | break; |
1474 | case FontVariantNumericFraction::DiagonalFractions: |
1475 | valueList->append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions)); |
1476 | break; |
1477 | case FontVariantNumericFraction::StackedFractions: |
1478 | valueList->append(cssValuePool.createIdentifierValue(CSSValueStackedFractions)); |
1479 | break; |
1480 | } |
1481 | |
1482 | if (ordinal == FontVariantNumericOrdinal::Yes) |
1483 | valueList->append(cssValuePool.createIdentifierValue(CSSValueOrdinal)); |
1484 | if (slashedZero == FontVariantNumericSlashedZero::Yes) |
1485 | valueList->append(cssValuePool.createIdentifierValue(CSSValueSlashedZero)); |
1486 | |
1487 | return valueList; |
1488 | } |
1489 | |
1490 | static Ref<CSSValue> fontVariantAlternatesPropertyValue(FontVariantAlternates alternates) |
1491 | { |
1492 | auto& cssValuePool = CSSValuePool::singleton(); |
1493 | CSSValueID valueID = CSSValueNormal; |
1494 | switch (alternates) { |
1495 | case FontVariantAlternates::Normal: |
1496 | break; |
1497 | case FontVariantAlternates::HistoricalForms: |
1498 | valueID = CSSValueHistoricalForms; |
1499 | break; |
1500 | } |
1501 | return cssValuePool.createIdentifierValue(valueID); |
1502 | } |
1503 | |
1504 | static Ref<CSSValue> fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby) |
1505 | { |
1506 | auto& cssValuePool = CSSValuePool::singleton(); |
1507 | if (variant == FontVariantEastAsianVariant::Normal && width == FontVariantEastAsianWidth::Normal && ruby == FontVariantEastAsianRuby::Normal) |
1508 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
1509 | |
1510 | auto valueList = CSSValueList::createSpaceSeparated(); |
1511 | switch (variant) { |
1512 | case FontVariantEastAsianVariant::Normal: |
1513 | break; |
1514 | case FontVariantEastAsianVariant::Jis78: |
1515 | valueList->append(cssValuePool.createIdentifierValue(CSSValueJis78)); |
1516 | break; |
1517 | case FontVariantEastAsianVariant::Jis83: |
1518 | valueList->append(cssValuePool.createIdentifierValue(CSSValueJis83)); |
1519 | break; |
1520 | case FontVariantEastAsianVariant::Jis90: |
1521 | valueList->append(cssValuePool.createIdentifierValue(CSSValueJis90)); |
1522 | break; |
1523 | case FontVariantEastAsianVariant::Jis04: |
1524 | valueList->append(cssValuePool.createIdentifierValue(CSSValueJis04)); |
1525 | break; |
1526 | case FontVariantEastAsianVariant::Simplified: |
1527 | valueList->append(cssValuePool.createIdentifierValue(CSSValueSimplified)); |
1528 | break; |
1529 | case FontVariantEastAsianVariant::Traditional: |
1530 | valueList->append(cssValuePool.createIdentifierValue(CSSValueTraditional)); |
1531 | break; |
1532 | } |
1533 | |
1534 | switch (width) { |
1535 | case FontVariantEastAsianWidth::Normal: |
1536 | break; |
1537 | case FontVariantEastAsianWidth::Full: |
1538 | valueList->append(cssValuePool.createIdentifierValue(CSSValueFullWidth)); |
1539 | break; |
1540 | case FontVariantEastAsianWidth::Proportional: |
1541 | valueList->append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth)); |
1542 | break; |
1543 | } |
1544 | |
1545 | if (ruby == FontVariantEastAsianRuby::Yes) |
1546 | valueList->append(cssValuePool.createIdentifierValue(CSSValueRuby)); |
1547 | |
1548 | return valueList; |
1549 | } |
1550 | |
1551 | static Ref<CSSValueList> delayValue(const AnimationList* animationList) |
1552 | { |
1553 | auto& cssValuePool = CSSValuePool::singleton(); |
1554 | auto list = CSSValueList::createCommaSeparated(); |
1555 | if (animationList) { |
1556 | for (size_t i = 0; i < animationList->size(); ++i) |
1557 | list->append(cssValuePool.createValue(animationList->animation(i).delay(), CSSPrimitiveValue::CSS_S)); |
1558 | } else { |
1559 | // Note that initialAnimationDelay() is used for both transitions and animations |
1560 | list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S)); |
1561 | } |
1562 | return list; |
1563 | } |
1564 | |
1565 | static Ref<CSSValueList> durationValue(const AnimationList* animationList) |
1566 | { |
1567 | auto& cssValuePool = CSSValuePool::singleton(); |
1568 | auto list = CSSValueList::createCommaSeparated(); |
1569 | if (animationList) { |
1570 | for (size_t i = 0; i < animationList->size(); ++i) |
1571 | list->append(cssValuePool.createValue(animationList->animation(i).duration(), CSSPrimitiveValue::CSS_S)); |
1572 | } else { |
1573 | // Note that initialAnimationDuration() is used for both transitions and animations |
1574 | list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S)); |
1575 | } |
1576 | return list; |
1577 | } |
1578 | |
1579 | static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunction) |
1580 | { |
1581 | switch (timingFunction.type()) { |
1582 | case TimingFunction::CubicBezierFunction: { |
1583 | auto& function = downcast<CubicBezierTimingFunction>(timingFunction); |
1584 | if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) { |
1585 | CSSValueID valueId = CSSValueInvalid; |
1586 | switch (function.timingFunctionPreset()) { |
1587 | case CubicBezierTimingFunction::Ease: |
1588 | valueId = CSSValueEase; |
1589 | break; |
1590 | case CubicBezierTimingFunction::EaseIn: |
1591 | valueId = CSSValueEaseIn; |
1592 | break; |
1593 | case CubicBezierTimingFunction::EaseOut: |
1594 | valueId = CSSValueEaseOut; |
1595 | break; |
1596 | default: |
1597 | ASSERT(function.timingFunctionPreset() == CubicBezierTimingFunction::EaseInOut); |
1598 | valueId = CSSValueEaseInOut; |
1599 | break; |
1600 | } |
1601 | return CSSValuePool::singleton().createIdentifierValue(valueId); |
1602 | } |
1603 | return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2()); |
1604 | } |
1605 | case TimingFunction::StepsFunction: { |
1606 | auto& function = downcast<StepsTimingFunction>(timingFunction); |
1607 | return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart()); |
1608 | } |
1609 | case TimingFunction::SpringFunction: { |
1610 | auto& function = downcast<SpringTimingFunction>(timingFunction); |
1611 | return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity()); |
1612 | } |
1613 | default: |
1614 | ASSERT(timingFunction.type() == TimingFunction::LinearFunction); |
1615 | return CSSValuePool::singleton().createIdentifierValue(CSSValueLinear); |
1616 | } |
1617 | } |
1618 | |
1619 | static Ref<CSSValueList> timingFunctionValue(const AnimationList* animationList) |
1620 | { |
1621 | auto list = CSSValueList::createCommaSeparated(); |
1622 | if (animationList) { |
1623 | for (size_t i = 0; i < animationList->size(); ++i) |
1624 | list->append(createTimingFunctionValue(*animationList->animation(i).timingFunction())); |
1625 | } else |
1626 | // Note that initialAnimationTimingFunction() is used for both transitions and animations |
1627 | list->append(createTimingFunctionValue(Animation::initialTimingFunction())); |
1628 | return list; |
1629 | } |
1630 | |
1631 | static Ref<CSSValue> createLineBoxContainValue(unsigned lineBoxContain) |
1632 | { |
1633 | if (!lineBoxContain) |
1634 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1635 | return CSSLineBoxContainValue::create(lineBoxContain); |
1636 | } |
1637 | |
1638 | static Element* styleElementForNode(Node* node) |
1639 | { |
1640 | if (!node) |
1641 | return nullptr; |
1642 | if (is<Element>(*node)) |
1643 | return downcast<Element>(node); |
1644 | return composedTreeAncestors(*node).first(); |
1645 | } |
1646 | |
1647 | ComputedStyleExtractor::(Node* node, bool allowVisitedStyle, PseudoId pseudoElementSpecifier) |
1648 | : m_element(styleElementForNode(node)) |
1649 | , m_pseudoElementSpecifier(pseudoElementSpecifier) |
1650 | , m_allowVisitedStyle(allowVisitedStyle) |
1651 | { |
1652 | } |
1653 | |
1654 | ComputedStyleExtractor::(Element* element, bool allowVisitedStyle, PseudoId pseudoElementSpecifier) |
1655 | : m_element(element) |
1656 | , m_pseudoElementSpecifier(pseudoElementSpecifier) |
1657 | , m_allowVisitedStyle(allowVisitedStyle) |
1658 | { |
1659 | } |
1660 | |
1661 | CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(Element& element, bool allowVisitedStyle, const String& pseudoElementName) |
1662 | : m_element(element) |
1663 | , m_allowVisitedStyle(allowVisitedStyle) |
1664 | , m_refCount(1) |
1665 | { |
1666 | unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0; |
1667 | m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoElementType( |
1668 | (pseudoElementName.substringSharingImpl(nameWithoutColonsStart)))); |
1669 | } |
1670 | |
1671 | CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration() = default; |
1672 | |
1673 | void CSSComputedStyleDeclaration::ref() |
1674 | { |
1675 | ++m_refCount; |
1676 | } |
1677 | |
1678 | void CSSComputedStyleDeclaration::deref() |
1679 | { |
1680 | ASSERT(m_refCount); |
1681 | if (!--m_refCount) |
1682 | delete this; |
1683 | } |
1684 | |
1685 | String CSSComputedStyleDeclaration::cssText() const |
1686 | { |
1687 | StringBuilder result; |
1688 | |
1689 | for (unsigned i = 0; i < numComputedProperties; i++) { |
1690 | if (i) |
1691 | result.append(' '); |
1692 | result.append(getPropertyName(computedProperties[i])); |
1693 | result.appendLiteral(": " ); |
1694 | result.append(getPropertyValue(computedProperties[i])); |
1695 | result.append(';'); |
1696 | } |
1697 | |
1698 | return result.toString(); |
1699 | } |
1700 | |
1701 | ExceptionOr<void> CSSComputedStyleDeclaration::setCssText(const String&) |
1702 | { |
1703 | return Exception { NoModificationAllowedError }; |
1704 | } |
1705 | |
1706 | RefPtr<CSSPrimitiveValue> ComputedStyleExtractor::() |
1707 | { |
1708 | if (!m_element) |
1709 | return nullptr; |
1710 | |
1711 | m_element->document().updateLayoutIgnorePendingStylesheets(); |
1712 | |
1713 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
1714 | if (!style) |
1715 | return nullptr; |
1716 | |
1717 | if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) |
1718 | return CSSValuePool::singleton().createIdentifierValue(sizeIdentifier); |
1719 | |
1720 | return zoomAdjustedPixelValue(style->fontDescription().computedSize(), *style); |
1721 | } |
1722 | |
1723 | bool ComputedStyleExtractor::() |
1724 | { |
1725 | if (!m_element) |
1726 | return false; |
1727 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
1728 | if (!style) |
1729 | return false; |
1730 | |
1731 | return style->fontDescription().useFixedDefaultSize(); |
1732 | } |
1733 | |
1734 | static CSSValueID identifierForFamily(const AtomString& family) |
1735 | { |
1736 | if (family == cursiveFamily) |
1737 | return CSSValueCursive; |
1738 | if (family == fantasyFamily) |
1739 | return CSSValueFantasy; |
1740 | if (family == monospaceFamily) |
1741 | return CSSValueMonospace; |
1742 | if (family == pictographFamily) |
1743 | return CSSValueWebkitPictograph; |
1744 | if (family == sansSerifFamily) |
1745 | return CSSValueSansSerif; |
1746 | if (family == serifFamily) |
1747 | return CSSValueSerif; |
1748 | if (family == systemUiFamily) |
1749 | return CSSValueSystemUi; |
1750 | return CSSValueInvalid; |
1751 | } |
1752 | |
1753 | static Ref<CSSPrimitiveValue> valueForFamily(const AtomString& family) |
1754 | { |
1755 | if (CSSValueID familyIdentifier = identifierForFamily(family)) |
1756 | return CSSValuePool::singleton().createIdentifierValue(familyIdentifier); |
1757 | return CSSValuePool::singleton().createFontFamilyValue(family); |
1758 | } |
1759 | |
1760 | #if ENABLE(POINTER_EVENTS) |
1761 | static Ref<CSSValue> touchActionFlagsToCSSValue(OptionSet<TouchAction> touchActions) |
1762 | { |
1763 | auto& cssValuePool = CSSValuePool::singleton(); |
1764 | |
1765 | if (touchActions & TouchAction::Auto) |
1766 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
1767 | if (touchActions & TouchAction::None) |
1768 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1769 | if (touchActions & TouchAction::Manipulation) |
1770 | return cssValuePool.createIdentifierValue(CSSValueManipulation); |
1771 | |
1772 | auto list = CSSValueList::createSpaceSeparated(); |
1773 | if (touchActions & TouchAction::PanX) |
1774 | list->append(cssValuePool.createIdentifierValue(CSSValuePanX)); |
1775 | if (touchActions & TouchAction::PanY) |
1776 | list->append(cssValuePool.createIdentifierValue(CSSValuePanY)); |
1777 | if (touchActions & TouchAction::PinchZoom) |
1778 | list->append(cssValuePool.createIdentifierValue(CSSValuePinchZoom)); |
1779 | |
1780 | if (!list->length()) |
1781 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
1782 | return list; |
1783 | } |
1784 | #endif |
1785 | |
1786 | static Ref<CSSValue> renderTextDecorationFlagsToCSSValue(OptionSet<TextDecoration> textDecoration) |
1787 | { |
1788 | auto& cssValuePool = CSSValuePool::singleton(); |
1789 | // Blink value is ignored. |
1790 | auto list = CSSValueList::createSpaceSeparated(); |
1791 | if (textDecoration & TextDecoration::Underline) |
1792 | list->append(cssValuePool.createIdentifierValue(CSSValueUnderline)); |
1793 | if (textDecoration & TextDecoration::Overline) |
1794 | list->append(cssValuePool.createIdentifierValue(CSSValueOverline)); |
1795 | if (textDecoration & TextDecoration::LineThrough) |
1796 | list->append(cssValuePool.createIdentifierValue(CSSValueLineThrough)); |
1797 | #if ENABLE(LETTERPRESS) |
1798 | if (textDecoration & TextDecoration::Letterpress) |
1799 | list->append(cssValuePool.createIdentifierValue(CSSValueWebkitLetterpress)); |
1800 | #endif |
1801 | |
1802 | if (!list->length()) |
1803 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1804 | return list; |
1805 | } |
1806 | |
1807 | static Ref<CSSValue> renderTextDecorationStyleFlagsToCSSValue(TextDecorationStyle textDecorationStyle) |
1808 | { |
1809 | switch (textDecorationStyle) { |
1810 | case TextDecorationStyle::Solid: |
1811 | return CSSValuePool::singleton().createIdentifierValue(CSSValueSolid); |
1812 | case TextDecorationStyle::Double: |
1813 | return CSSValuePool::singleton().createIdentifierValue(CSSValueDouble); |
1814 | case TextDecorationStyle::Dotted: |
1815 | return CSSValuePool::singleton().createIdentifierValue(CSSValueDotted); |
1816 | case TextDecorationStyle::Dashed: |
1817 | return CSSValuePool::singleton().createIdentifierValue(CSSValueDashed); |
1818 | case TextDecorationStyle::Wavy: |
1819 | return CSSValuePool::singleton().createIdentifierValue(CSSValueWavy); |
1820 | } |
1821 | |
1822 | ASSERT_NOT_REACHED(); |
1823 | return CSSValuePool::singleton().createExplicitInitialValue(); |
1824 | } |
1825 | |
1826 | static Ref<CSSValue> renderTextDecorationSkipFlagsToCSSValue(OptionSet<TextDecorationSkip> textDecorationSkip) |
1827 | { |
1828 | // FIXME: This should probably return a CSSValueList with the set of all TextDecorationSkips. |
1829 | switch (static_cast<TextDecorationSkip>(textDecorationSkip.toRaw())) { |
1830 | case TextDecorationSkip::Auto: |
1831 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
1832 | case TextDecorationSkip::None: |
1833 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1834 | case TextDecorationSkip::Ink: |
1835 | return CSSValuePool::singleton().createIdentifierValue(CSSValueInk); |
1836 | case TextDecorationSkip::Objects: |
1837 | return CSSValuePool::singleton().createIdentifierValue(CSSValueObjects); |
1838 | } |
1839 | |
1840 | ASSERT_NOT_REACHED(); |
1841 | return CSSValuePool::singleton().createExplicitInitialValue(); |
1842 | } |
1843 | |
1844 | static Ref<CSSValue> textUnderlineOffsetToCSSValue(const TextUnderlineOffset& textUnderlineOffset) |
1845 | { |
1846 | if (textUnderlineOffset.isAuto()) |
1847 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
1848 | ASSERT(textUnderlineOffset.isLength()); |
1849 | return CSSValuePool::singleton().createValue(textUnderlineOffset.lengthValue(), CSSPrimitiveValue::CSS_PX); |
1850 | } |
1851 | |
1852 | static Ref<CSSValue> textDecorationThicknessToCSSValue(const TextDecorationThickness& textDecorationThickness) |
1853 | { |
1854 | if (textDecorationThickness.isAuto()) |
1855 | return CSSValuePool::singleton().createIdentifierValue(CSSValueAuto); |
1856 | if (textDecorationThickness.isFromFont()) |
1857 | return CSSValuePool::singleton().createIdentifierValue(CSSValueFromFont); |
1858 | ASSERT(textDecorationThickness.isLength()); |
1859 | return CSSValuePool::singleton().createValue(textDecorationThickness.lengthValue(), CSSPrimitiveValue::CSS_PX); |
1860 | } |
1861 | |
1862 | static Ref<CSSValue> renderEmphasisPositionFlagsToCSSValue(OptionSet<TextEmphasisPosition> textEmphasisPosition) |
1863 | { |
1864 | ASSERT(!((textEmphasisPosition & TextEmphasisPosition::Over) && (textEmphasisPosition & TextEmphasisPosition::Under))); |
1865 | ASSERT(!((textEmphasisPosition & TextEmphasisPosition::Left) && (textEmphasisPosition & TextEmphasisPosition::Right))); |
1866 | auto& cssValuePool = CSSValuePool::singleton(); |
1867 | auto list = CSSValueList::createSpaceSeparated(); |
1868 | if (textEmphasisPosition & TextEmphasisPosition::Over) |
1869 | list->append(cssValuePool.createIdentifierValue(CSSValueOver)); |
1870 | if (textEmphasisPosition & TextEmphasisPosition::Under) |
1871 | list->append(cssValuePool.createIdentifierValue(CSSValueUnder)); |
1872 | if (textEmphasisPosition & TextEmphasisPosition::Left) |
1873 | list->append(cssValuePool.createIdentifierValue(CSSValueLeft)); |
1874 | if (textEmphasisPosition & TextEmphasisPosition::Right) |
1875 | list->append(cssValuePool.createIdentifierValue(CSSValueRight)); |
1876 | if (!list->length()) |
1877 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1878 | return list; |
1879 | } |
1880 | |
1881 | static Ref<CSSValue> speakAsToCSSValue(OptionSet<SpeakAs> speakAs) |
1882 | { |
1883 | auto& cssValuePool = CSSValuePool::singleton(); |
1884 | auto list = CSSValueList::createSpaceSeparated(); |
1885 | if (speakAs & SpeakAs::SpellOut) |
1886 | list->append(cssValuePool.createIdentifierValue(CSSValueSpellOut)); |
1887 | if (speakAs & SpeakAs::Digits) |
1888 | list->append(cssValuePool.createIdentifierValue(CSSValueDigits)); |
1889 | if (speakAs & SpeakAs::LiteralPunctuation) |
1890 | list->append(cssValuePool.createIdentifierValue(CSSValueLiteralPunctuation)); |
1891 | if (speakAs & SpeakAs::NoPunctuation) |
1892 | list->append(cssValuePool.createIdentifierValue(CSSValueNoPunctuation)); |
1893 | if (!list->length()) |
1894 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
1895 | return list; |
1896 | } |
1897 | |
1898 | static Ref<CSSValue> hangingPunctuationToCSSValue(OptionSet<HangingPunctuation> hangingPunctuation) |
1899 | { |
1900 | auto& cssValuePool = CSSValuePool::singleton(); |
1901 | auto list = CSSValueList::createSpaceSeparated(); |
1902 | if (hangingPunctuation & HangingPunctuation::First) |
1903 | list->append(cssValuePool.createIdentifierValue(CSSValueFirst)); |
1904 | if (hangingPunctuation & HangingPunctuation::AllowEnd) |
1905 | list->append(cssValuePool.createIdentifierValue(CSSValueAllowEnd)); |
1906 | if (hangingPunctuation & HangingPunctuation::ForceEnd) |
1907 | list->append(cssValuePool.createIdentifierValue(CSSValueForceEnd)); |
1908 | if (hangingPunctuation & HangingPunctuation::Last) |
1909 | list->append(cssValuePool.createIdentifierValue(CSSValueLast)); |
1910 | if (!list->length()) |
1911 | return cssValuePool.createIdentifierValue(CSSValueNone); |
1912 | return list; |
1913 | } |
1914 | |
1915 | static Ref<CSSValue> fillRepeatToCSSValue(FillRepeat xRepeat, FillRepeat yRepeat) |
1916 | { |
1917 | // For backwards compatibility, if both values are equal, just return one of them. And |
1918 | // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand. |
1919 | auto& cssValuePool = CSSValuePool::singleton(); |
1920 | if (xRepeat == yRepeat) |
1921 | return cssValuePool.createValue(xRepeat); |
1922 | if (xRepeat == FillRepeat::Repeat && yRepeat == FillRepeat::NoRepeat) |
1923 | return cssValuePool.createIdentifierValue(CSSValueRepeatX); |
1924 | if (xRepeat == FillRepeat::NoRepeat && yRepeat == FillRepeat::Repeat) |
1925 | return cssValuePool.createIdentifierValue(CSSValueRepeatY); |
1926 | |
1927 | auto list = CSSValueList::createSpaceSeparated(); |
1928 | list->append(cssValuePool.createValue(xRepeat)); |
1929 | list->append(cssValuePool.createValue(yRepeat)); |
1930 | return list; |
1931 | } |
1932 | |
1933 | static Ref<CSSValue> fillSourceTypeToCSSValue(MaskSourceType type) |
1934 | { |
1935 | switch (type) { |
1936 | case MaskSourceType::Alpha: |
1937 | return CSSValuePool::singleton().createValue(CSSValueAlpha); |
1938 | default: |
1939 | ASSERT(type == MaskSourceType::Luminance); |
1940 | return CSSValuePool::singleton().createValue(CSSValueLuminance); |
1941 | } |
1942 | } |
1943 | |
1944 | static Ref<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, const RenderStyle& style) |
1945 | { |
1946 | if (fillSize.type == FillSizeType::Contain) |
1947 | return CSSValuePool::singleton().createIdentifierValue(CSSValueContain); |
1948 | |
1949 | if (fillSize.type == FillSizeType::Cover) |
1950 | return CSSValuePool::singleton().createIdentifierValue(CSSValueCover); |
1951 | |
1952 | if (fillSize.size.height.isAuto()) |
1953 | return zoomAdjustedPixelValueForLength(fillSize.size.width, style); |
1954 | |
1955 | auto list = CSSValueList::createSpaceSeparated(); |
1956 | list->append(zoomAdjustedPixelValueForLength(fillSize.size.width, style)); |
1957 | list->append(zoomAdjustedPixelValueForLength(fillSize.size.height, style)); |
1958 | return list; |
1959 | } |
1960 | |
1961 | static Ref<CSSValue> altTextToCSSValue(const RenderStyle& style) |
1962 | { |
1963 | return CSSValuePool::singleton().createValue(style.contentAltText(), CSSPrimitiveValue::CSS_STRING); |
1964 | } |
1965 | |
1966 | static Ref<CSSValueList> contentToCSSValue(const RenderStyle& style) |
1967 | { |
1968 | auto& cssValuePool = CSSValuePool::singleton(); |
1969 | auto list = CSSValueList::createSpaceSeparated(); |
1970 | for (auto* contentData = style.contentData(); contentData; contentData = contentData->next()) { |
1971 | if (is<CounterContentData>(*contentData)) |
1972 | list->append(cssValuePool.createValue(downcast<CounterContentData>(*contentData).counter().identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME)); |
1973 | else if (is<ImageContentData>(*contentData)) |
1974 | list->append(downcast<ImageContentData>(*contentData).image().cssValue()); |
1975 | else if (is<TextContentData>(*contentData)) |
1976 | list->append(cssValuePool.createValue(downcast<TextContentData>(*contentData).text(), CSSPrimitiveValue::CSS_STRING)); |
1977 | } |
1978 | return list; |
1979 | } |
1980 | |
1981 | static Ref<CSSValue> counterToCSSValue(const RenderStyle& style, CSSPropertyID propertyID) |
1982 | { |
1983 | auto* map = style.counterDirectives(); |
1984 | if (!map) |
1985 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
1986 | |
1987 | auto& cssValuePool = CSSValuePool::singleton(); |
1988 | auto list = CSSValueList::createSpaceSeparated(); |
1989 | for (auto& keyValue : *map) { |
1990 | list->append(cssValuePool.createValue(keyValue.key, CSSPrimitiveValue::CSS_STRING)); |
1991 | double number = (propertyID == CSSPropertyCounterIncrement ? keyValue.value.incrementValue : keyValue.value.resetValue).valueOr(0); |
1992 | list->append(cssValuePool.createValue(number, CSSPrimitiveValue::CSS_NUMBER)); |
1993 | } |
1994 | return list; |
1995 | } |
1996 | |
1997 | static void logUnimplementedPropertyID(CSSPropertyID propertyID) |
1998 | { |
1999 | static NeverDestroyed<HashSet<CSSPropertyID>> propertyIDSet; |
2000 | if (!propertyIDSet.get().add(propertyID).isNewEntry) |
2001 | return; |
2002 | |
2003 | LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'." , getPropertyName(propertyID)); |
2004 | } |
2005 | |
2006 | static Ref<CSSValueList> fontFamilyListFromStyle(const RenderStyle& style) |
2007 | { |
2008 | auto list = CSSValueList::createCommaSeparated(); |
2009 | for (unsigned i = 0; i < style.fontCascade().familyCount(); ++i) |
2010 | list->append(valueForFamily(style.fontCascade().familyAt(i))); |
2011 | return list; |
2012 | } |
2013 | |
2014 | static Ref<CSSValue> fontFamilyFromStyle(const RenderStyle& style) |
2015 | { |
2016 | if (style.fontCascade().familyCount() == 1) |
2017 | return valueForFamily(style.fontCascade().familyAt(0)); |
2018 | return fontFamilyListFromStyle(style); |
2019 | } |
2020 | |
2021 | static Ref<CSSPrimitiveValue> lineHeightFromStyle(const RenderStyle& style) |
2022 | { |
2023 | Length length = style.lineHeight(); |
2024 | if (length.isNegative()) // If true, line-height not set; use the font's line spacing. |
2025 | return zoomAdjustedPixelValue(style.fontMetrics().floatLineSpacing(), style); |
2026 | if (length.isPercent()) { |
2027 | // This is imperfect, because it doesn't include the zoom factor and the real computation |
2028 | // for how high to be in pixels does include things like minimum font size and the zoom factor. |
2029 | // On the other hand, since font-size doesn't include the zoom factor, we really can't do |
2030 | // that here either. |
2031 | return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style.fontDescription().computedSize()) / 100, style); |
2032 | } |
2033 | return zoomAdjustedPixelValue(floatValueForLength(length, 0), style); |
2034 | } |
2035 | |
2036 | static Ref<CSSPrimitiveValue> fontSizeFromStyle(const RenderStyle& style) |
2037 | { |
2038 | return zoomAdjustedPixelValue(style.fontDescription().computedSize(), style); |
2039 | } |
2040 | |
2041 | Ref<CSSPrimitiveValue> ComputedStyleExtractor::(FontSelectionValue weight) |
2042 | { |
2043 | return CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSPrimitiveValue::CSS_NUMBER); |
2044 | } |
2045 | |
2046 | Ref<CSSPrimitiveValue> ComputedStyleExtractor::(FontSelectionValue weight) |
2047 | { |
2048 | if (auto value = fontWeightKeyword(weight)) |
2049 | return CSSValuePool::singleton().createIdentifierValue(value.value()); |
2050 | return fontNonKeywordWeightFromStyleValue(weight); |
2051 | } |
2052 | |
2053 | static Ref<CSSPrimitiveValue> fontWeightFromStyle(const RenderStyle& style) |
2054 | { |
2055 | return ComputedStyleExtractor::fontWeightFromStyleValue(style.fontDescription().weight()); |
2056 | } |
2057 | |
2058 | Ref<CSSPrimitiveValue> ComputedStyleExtractor::(FontSelectionValue stretch) |
2059 | { |
2060 | return CSSValuePool::singleton().createValue(static_cast<float>(stretch), CSSPrimitiveValue::CSS_PERCENTAGE); |
2061 | } |
2062 | |
2063 | Ref<CSSPrimitiveValue> ComputedStyleExtractor::(FontSelectionValue stretch) |
2064 | { |
2065 | if (auto keyword = fontStretchKeyword(stretch)) |
2066 | return CSSValuePool::singleton().createIdentifierValue(keyword.value()); |
2067 | return fontNonKeywordStretchFromStyleValue(stretch); |
2068 | } |
2069 | |
2070 | static Ref<CSSPrimitiveValue> fontStretchFromStyle(const RenderStyle& style) |
2071 | { |
2072 | return ComputedStyleExtractor::fontStretchFromStyleValue(style.fontDescription().stretch()); |
2073 | } |
2074 | |
2075 | Ref<CSSFontStyleValue> ComputedStyleExtractor::(FontSelectionValue italic) |
2076 | { |
2077 | return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), CSSValuePool::singleton().createValue(static_cast<float>(italic), CSSPrimitiveValue::CSS_DEG)); |
2078 | } |
2079 | |
2080 | Ref<CSSFontStyleValue> ComputedStyleExtractor::(Optional<FontSelectionValue> italic, FontStyleAxis fontStyleAxis) |
2081 | { |
2082 | if (auto keyword = fontStyleKeyword(italic, fontStyleAxis)) |
2083 | return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(keyword.value())); |
2084 | return fontNonKeywordStyleFromStyleValue(italic.value()); |
2085 | } |
2086 | |
2087 | static Ref<CSSFontStyleValue> fontStyleFromStyle(const RenderStyle& style) |
2088 | { |
2089 | return ComputedStyleExtractor::fontStyleFromStyleValue(style.fontDescription().italic(), style.fontDescription().fontStyleAxis()); |
2090 | } |
2091 | |
2092 | static Ref<CSSValue> fontVariantFromStyle(const RenderStyle& style) |
2093 | { |
2094 | if (style.fontDescription().variantSettings().isAllNormal()) |
2095 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); |
2096 | |
2097 | auto list = CSSValueList::createSpaceSeparated(); |
2098 | |
2099 | switch (style.fontDescription().variantCommonLigatures()) { |
2100 | case FontVariantLigatures::Normal: |
2101 | break; |
2102 | case FontVariantLigatures::Yes: |
2103 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueCommonLigatures)); |
2104 | break; |
2105 | case FontVariantLigatures::No: |
2106 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoCommonLigatures)); |
2107 | break; |
2108 | } |
2109 | |
2110 | switch (style.fontDescription().variantDiscretionaryLigatures()) { |
2111 | case FontVariantLigatures::Normal: |
2112 | break; |
2113 | case FontVariantLigatures::Yes: |
2114 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiscretionaryLigatures)); |
2115 | break; |
2116 | case FontVariantLigatures::No: |
2117 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoDiscretionaryLigatures)); |
2118 | break; |
2119 | } |
2120 | |
2121 | switch (style.fontDescription().variantHistoricalLigatures()) { |
2122 | case FontVariantLigatures::Normal: |
2123 | break; |
2124 | case FontVariantLigatures::Yes: |
2125 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalLigatures)); |
2126 | break; |
2127 | case FontVariantLigatures::No: |
2128 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoHistoricalLigatures)); |
2129 | break; |
2130 | } |
2131 | |
2132 | switch (style.fontDescription().variantContextualAlternates()) { |
2133 | case FontVariantLigatures::Normal: |
2134 | break; |
2135 | case FontVariantLigatures::Yes: |
2136 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueContextual)); |
2137 | break; |
2138 | case FontVariantLigatures::No: |
2139 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueNoContextual)); |
2140 | break; |
2141 | } |
2142 | |
2143 | switch (style.fontDescription().variantPosition()) { |
2144 | case FontVariantPosition::Normal: |
2145 | break; |
2146 | case FontVariantPosition::Subscript: |
2147 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSub)); |
2148 | break; |
2149 | case FontVariantPosition::Superscript: |
2150 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSuper)); |
2151 | break; |
2152 | } |
2153 | |
2154 | switch (style.fontDescription().variantCaps()) { |
2155 | case FontVariantCaps::Normal: |
2156 | break; |
2157 | case FontVariantCaps::Small: |
2158 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); |
2159 | break; |
2160 | case FontVariantCaps::AllSmall: |
2161 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllSmallCaps)); |
2162 | break; |
2163 | case FontVariantCaps::Petite: |
2164 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValuePetiteCaps)); |
2165 | break; |
2166 | case FontVariantCaps::AllPetite: |
2167 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueAllPetiteCaps)); |
2168 | break; |
2169 | case FontVariantCaps::Unicase: |
2170 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueUnicase)); |
2171 | break; |
2172 | case FontVariantCaps::Titling: |
2173 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTitlingCaps)); |
2174 | break; |
2175 | } |
2176 | |
2177 | switch (style.fontDescription().variantNumericFigure()) { |
2178 | case FontVariantNumericFigure::Normal: |
2179 | break; |
2180 | case FontVariantNumericFigure::LiningNumbers: |
2181 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueLiningNums)); |
2182 | break; |
2183 | case FontVariantNumericFigure::OldStyleNumbers: |
2184 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOldstyleNums)); |
2185 | break; |
2186 | } |
2187 | |
2188 | switch (style.fontDescription().variantNumericSpacing()) { |
2189 | case FontVariantNumericSpacing::Normal: |
2190 | break; |
2191 | case FontVariantNumericSpacing::ProportionalNumbers: |
2192 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalNums)); |
2193 | break; |
2194 | case FontVariantNumericSpacing::TabularNumbers: |
2195 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTabularNums)); |
2196 | break; |
2197 | } |
2198 | |
2199 | switch (style.fontDescription().variantNumericFraction()) { |
2200 | case FontVariantNumericFraction::Normal: |
2201 | break; |
2202 | case FontVariantNumericFraction::DiagonalFractions: |
2203 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueDiagonalFractions)); |
2204 | break; |
2205 | case FontVariantNumericFraction::StackedFractions: |
2206 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStackedFractions)); |
2207 | break; |
2208 | } |
2209 | |
2210 | switch (style.fontDescription().variantNumericOrdinal()) { |
2211 | case FontVariantNumericOrdinal::Normal: |
2212 | break; |
2213 | case FontVariantNumericOrdinal::Yes: |
2214 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueOrdinal)); |
2215 | break; |
2216 | } |
2217 | |
2218 | switch (style.fontDescription().variantNumericSlashedZero()) { |
2219 | case FontVariantNumericSlashedZero::Normal: |
2220 | break; |
2221 | case FontVariantNumericSlashedZero::Yes: |
2222 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSlashedZero)); |
2223 | break; |
2224 | } |
2225 | |
2226 | switch (style.fontDescription().variantAlternates()) { |
2227 | case FontVariantAlternates::Normal: |
2228 | break; |
2229 | case FontVariantAlternates::HistoricalForms: |
2230 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueHistoricalForms)); |
2231 | break; |
2232 | } |
2233 | |
2234 | switch (style.fontDescription().variantEastAsianVariant()) { |
2235 | case FontVariantEastAsianVariant::Normal: |
2236 | break; |
2237 | case FontVariantEastAsianVariant::Jis78: |
2238 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis78)); |
2239 | break; |
2240 | case FontVariantEastAsianVariant::Jis83: |
2241 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis83)); |
2242 | break; |
2243 | case FontVariantEastAsianVariant::Jis90: |
2244 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis90)); |
2245 | break; |
2246 | case FontVariantEastAsianVariant::Jis04: |
2247 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueJis04)); |
2248 | break; |
2249 | case FontVariantEastAsianVariant::Simplified: |
2250 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSimplified)); |
2251 | break; |
2252 | case FontVariantEastAsianVariant::Traditional: |
2253 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueTraditional)); |
2254 | break; |
2255 | } |
2256 | |
2257 | switch (style.fontDescription().variantEastAsianWidth()) { |
2258 | case FontVariantEastAsianWidth::Normal: |
2259 | break; |
2260 | case FontVariantEastAsianWidth::Full: |
2261 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueFullWidth)); |
2262 | break; |
2263 | case FontVariantEastAsianWidth::Proportional: |
2264 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueProportionalWidth)); |
2265 | break; |
2266 | } |
2267 | |
2268 | switch (style.fontDescription().variantEastAsianRuby()) { |
2269 | case FontVariantEastAsianRuby::Normal: |
2270 | break; |
2271 | case FontVariantEastAsianRuby::Yes: |
2272 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby)); |
2273 | break; |
2274 | } |
2275 | |
2276 | return list; |
2277 | } |
2278 | |
2279 | static Ref<CSSValue> fontSynthesisFromStyle(const RenderStyle& style) |
2280 | { |
2281 | if (style.fontDescription().fontSynthesis() == FontSynthesisNone) |
2282 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
2283 | |
2284 | auto list = CSSValueList::createSpaceSeparated(); |
2285 | if (style.fontDescription().fontSynthesis() & FontSynthesisStyle) |
2286 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueStyle)); |
2287 | if (style.fontDescription().fontSynthesis() & FontSynthesisWeight) |
2288 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueWeight)); |
2289 | if (style.fontDescription().fontSynthesis() & FontSynthesisSmallCaps) |
2290 | list->append(CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps)); |
2291 | return list; |
2292 | } |
2293 | |
2294 | typedef const Length& (RenderStyle::*RenderStyleLengthGetter)() const; |
2295 | typedef LayoutUnit (RenderBoxModelObject::*RenderBoxComputedCSSValueGetter)() const; |
2296 | |
2297 | template<RenderStyleLengthGetter lengthGetter, RenderBoxComputedCSSValueGetter computedCSSValueGetter> |
2298 | static RefPtr<CSSValue> zoomAdjustedPaddingOrMarginPixelValue(const RenderStyle& style, RenderObject* renderer) |
2299 | { |
2300 | Length unzoomzedLength = (style.*lengthGetter)(); |
2301 | if (!is<RenderBox>(renderer) || unzoomzedLength.isFixed()) |
2302 | return zoomAdjustedPixelValueForLength(unzoomzedLength, style); |
2303 | return zoomAdjustedPixelValue((downcast<RenderBox>(*renderer).*computedCSSValueGetter)(), style); |
2304 | } |
2305 | |
2306 | template<RenderStyleLengthGetter lengthGetter> |
2307 | static bool paddingOrMarginIsRendererDependent(const RenderStyle* style, RenderObject* renderer) |
2308 | { |
2309 | return renderer && style && renderer->isBox() && !(style->*lengthGetter)().isFixed(); |
2310 | } |
2311 | |
2312 | static bool positionOffsetValueIsRendererDependent(const RenderStyle* style, RenderObject* renderer) |
2313 | { |
2314 | return renderer && style && renderer->isBox(); |
2315 | } |
2316 | |
2317 | static CSSValueID convertToPageBreak(BreakBetween value) |
2318 | { |
2319 | if (value == BreakBetween::Page || value == BreakBetween::LeftPage || value == BreakBetween::RightPage |
2320 | || value == BreakBetween::RectoPage || value == BreakBetween::VersoPage) |
2321 | return CSSValueAlways; // CSS 2.1 allows us to map these to always. |
2322 | if (value == BreakBetween::Avoid || value == BreakBetween::AvoidPage) |
2323 | return CSSValueAvoid; |
2324 | return CSSValueAuto; |
2325 | } |
2326 | |
2327 | static CSSValueID convertToColumnBreak(BreakBetween value) |
2328 | { |
2329 | if (value == BreakBetween::Column) |
2330 | return CSSValueAlways; |
2331 | if (value == BreakBetween::Avoid || value == BreakBetween::AvoidColumn) |
2332 | return CSSValueAvoid; |
2333 | return CSSValueAuto; |
2334 | } |
2335 | |
2336 | static CSSValueID convertToPageBreak(BreakInside value) |
2337 | { |
2338 | if (value == BreakInside::Avoid || value == BreakInside::AvoidPage) |
2339 | return CSSValueAvoid; |
2340 | return CSSValueAuto; |
2341 | } |
2342 | |
2343 | static CSSValueID convertToColumnBreak(BreakInside value) |
2344 | { |
2345 | if (value == BreakInside::Avoid || value == BreakInside::AvoidColumn) |
2346 | return CSSValueAvoid; |
2347 | return CSSValueAuto; |
2348 | } |
2349 | |
2350 | static inline bool isNonReplacedInline(RenderObject& renderer) |
2351 | { |
2352 | return renderer.isInline() && !renderer.isReplaced(); |
2353 | } |
2354 | |
2355 | static bool isLayoutDependent(CSSPropertyID propertyID, const RenderStyle* style, RenderObject* renderer) |
2356 | { |
2357 | switch (propertyID) { |
2358 | case CSSPropertyTop: |
2359 | case CSSPropertyBottom: |
2360 | case CSSPropertyLeft: |
2361 | case CSSPropertyRight: |
2362 | case CSSPropertyInsetBlockStart: |
2363 | case CSSPropertyInsetBlockEnd: |
2364 | case CSSPropertyInsetInlineStart: |
2365 | case CSSPropertyInsetInlineEnd: |
2366 | return positionOffsetValueIsRendererDependent(style, renderer); |
2367 | case CSSPropertyWidth: |
2368 | case CSSPropertyHeight: |
2369 | case CSSPropertyInlineSize: |
2370 | case CSSPropertyBlockSize: |
2371 | return renderer && !renderer->isRenderSVGModelObject() && !isNonReplacedInline(*renderer); |
2372 | case CSSPropertyPerspectiveOrigin: |
2373 | case CSSPropertyTransformOrigin: |
2374 | case CSSPropertyTransform: |
2375 | case CSSPropertyFilter: // Why are filters layout-dependent? |
2376 | #if ENABLE(FILTERS_LEVEL_2) |
2377 | case CSSPropertyWebkitBackdropFilter: // Ditto for backdrop-filter. |
2378 | #endif |
2379 | return true; |
2380 | case CSSPropertyMargin: { |
2381 | if (!renderer || !renderer->isBox()) |
2382 | return false; |
2383 | return !(style && style->marginTop().isFixed() && style->marginRight().isFixed() |
2384 | && style->marginBottom().isFixed() && style->marginLeft().isFixed()); |
2385 | } |
2386 | case CSSPropertyMarginTop: |
2387 | return paddingOrMarginIsRendererDependent<&RenderStyle::marginTop>(style, renderer); |
2388 | case CSSPropertyMarginRight: |
2389 | return paddingOrMarginIsRendererDependent<&RenderStyle::marginRight>(style, renderer); |
2390 | case CSSPropertyMarginBottom: |
2391 | return paddingOrMarginIsRendererDependent<&RenderStyle::marginBottom>(style, renderer); |
2392 | case CSSPropertyMarginLeft: |
2393 | return paddingOrMarginIsRendererDependent<&RenderStyle::marginLeft>(style, renderer); |
2394 | case CSSPropertyPadding: { |
2395 | if (!renderer || !renderer->isBox()) |
2396 | return false; |
2397 | return !(style && style->paddingTop().isFixed() && style->paddingRight().isFixed() |
2398 | && style->paddingBottom().isFixed() && style->paddingLeft().isFixed()); |
2399 | } |
2400 | case CSSPropertyPaddingTop: |
2401 | return paddingOrMarginIsRendererDependent<&RenderStyle::paddingTop>(style, renderer); |
2402 | case CSSPropertyPaddingRight: |
2403 | return paddingOrMarginIsRendererDependent<&RenderStyle::paddingRight>(style, renderer); |
2404 | case CSSPropertyPaddingBottom: |
2405 | return paddingOrMarginIsRendererDependent<&RenderStyle::paddingBottom>(style, renderer); |
2406 | case CSSPropertyPaddingLeft: |
2407 | return paddingOrMarginIsRendererDependent<&RenderStyle::paddingLeft>(style, renderer); |
2408 | case CSSPropertyGridTemplateColumns: |
2409 | case CSSPropertyGridTemplateRows: |
2410 | case CSSPropertyGridTemplate: |
2411 | case CSSPropertyGrid: |
2412 | return renderer && renderer->isRenderGrid(); |
2413 | default: |
2414 | return false; |
2415 | } |
2416 | } |
2417 | |
2418 | Element* ComputedStyleExtractor::() const |
2419 | { |
2420 | if (!m_element) |
2421 | return nullptr; |
2422 | PseudoElement* pseudoElement; |
2423 | if (m_pseudoElementSpecifier == PseudoId::Before && (pseudoElement = m_element->beforePseudoElement())) |
2424 | return pseudoElement; |
2425 | if (m_pseudoElementSpecifier == PseudoId::After && (pseudoElement = m_element->afterPseudoElement())) |
2426 | return pseudoElement; |
2427 | return m_element.get(); |
2428 | } |
2429 | |
2430 | RenderElement* ComputedStyleExtractor::() const |
2431 | { |
2432 | auto* element = styledElement(); |
2433 | if (!element) |
2434 | return nullptr; |
2435 | if (m_pseudoElementSpecifier != PseudoId::None && element == m_element.get()) |
2436 | return nullptr; |
2437 | if (element->hasDisplayContents()) |
2438 | return nullptr; |
2439 | return element->renderer(); |
2440 | } |
2441 | |
2442 | static bool isImplicitlyInheritedGridOrFlexProperty(CSSPropertyID propertyID) |
2443 | { |
2444 | // It would be nice if grid and flex worked within normal CSS mechanisms and not invented their own inheritance system. |
2445 | switch (propertyID) { |
2446 | case CSSPropertyAlignSelf: |
2447 | case CSSPropertyJustifySelf: |
2448 | case CSSPropertyJustifyItems: |
2449 | // FIXME: In StyleResolver::adjustRenderStyle z-index is adjusted based on the parent display property for grid/flex. |
2450 | case CSSPropertyZIndex: |
2451 | return true; |
2452 | default: |
2453 | return false; |
2454 | } |
2455 | } |
2456 | |
2457 | // In CSS 2.1 the returned object should actually contain the "used values" |
2458 | // rather then the "computed values" (despite the name saying otherwise). |
2459 | // |
2460 | // See; |
2461 | // http://www.w3.org/TR/CSS21/cascade.html#used-value |
2462 | // http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration |
2463 | // https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle#Notes |
2464 | RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const |
2465 | { |
2466 | return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).propertyValue(propertyID, updateLayout); |
2467 | } |
2468 | |
2469 | Ref<MutableStyleProperties> CSSComputedStyleDeclaration::copyProperties() const |
2470 | { |
2471 | return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).copyProperties(); |
2472 | } |
2473 | |
2474 | static inline bool hasValidStyleForProperty(Element& element, CSSPropertyID propertyID) |
2475 | { |
2476 | if (element.styleValidity() != Style::Validity::Valid) |
2477 | return false; |
2478 | if (element.document().hasPendingFullStyleRebuild()) |
2479 | return false; |
2480 | if (!element.document().childNeedsStyleRecalc()) |
2481 | return true; |
2482 | |
2483 | bool isInherited = CSSProperty::isInheritedProperty(propertyID) || isImplicitlyInheritedGridOrFlexProperty(propertyID); |
2484 | bool maybeExplicitlyInherited = !isInherited; |
2485 | |
2486 | const auto* currentElement = &element; |
2487 | for (auto& ancestor : composedTreeAncestors(element)) { |
2488 | if (ancestor.styleValidity() >= Style::Validity::SubtreeInvalid) |
2489 | return false; |
2490 | |
2491 | if (maybeExplicitlyInherited) { |
2492 | auto* style = currentElement->renderStyle(); |
2493 | maybeExplicitlyInherited = !style || style->hasExplicitlyInheritedProperties(); |
2494 | } |
2495 | |
2496 | if ((isInherited || maybeExplicitlyInherited) && ancestor.styleValidity() == Style::Validity::ElementInvalid) |
2497 | return false; |
2498 | |
2499 | if (ancestor.directChildNeedsStyleRecalc() && currentElement->styleIsAffectedByPreviousSibling()) |
2500 | return false; |
2501 | |
2502 | currentElement = &ancestor; |
2503 | } |
2504 | |
2505 | return true; |
2506 | } |
2507 | |
2508 | static bool updateStyleIfNeededForProperty(Element& element, CSSPropertyID propertyID) |
2509 | { |
2510 | auto& document = element.document(); |
2511 | |
2512 | document.styleScope().flushPendingUpdate(); |
2513 | |
2514 | if (hasValidStyleForProperty(element, propertyID)) |
2515 | return false; |
2516 | |
2517 | document.updateStyleIfNeeded(); |
2518 | return true; |
2519 | } |
2520 | |
2521 | static inline const RenderStyle* computeRenderStyleForProperty(Element& element, PseudoId pseudoElementSpecifier, CSSPropertyID propertyID, std::unique_ptr<RenderStyle>& ownedStyle) |
2522 | { |
2523 | auto* renderer = element.renderer(); |
2524 | |
2525 | if (renderer && renderer->isComposited() && CSSAnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) { |
2526 | if (auto timeline = element.document().existingTimeline()) |
2527 | ownedStyle = timeline->animatedStyleForRenderer(*renderer); |
2528 | else |
2529 | ownedStyle = renderer->animation().animatedStyleForRenderer(*renderer); |
2530 | if (pseudoElementSpecifier != PseudoId::None && !element.isPseudoElement()) { |
2531 | // FIXME: This cached pseudo style will only exist if the animation has been run at least once. |
2532 | return ownedStyle->getCachedPseudoStyle(pseudoElementSpecifier); |
2533 | } |
2534 | return ownedStyle.get(); |
2535 | } |
2536 | |
2537 | return element.computedStyle(element.isPseudoElement() ? PseudoId::None : pseudoElementSpecifier); |
2538 | } |
2539 | |
2540 | static Ref<CSSValue> shapePropertyValue(const RenderStyle& style, const ShapeValue* shapeValue) |
2541 | { |
2542 | if (!shapeValue) |
2543 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
2544 | |
2545 | if (shapeValue->type() == ShapeValue::Type::Box) |
2546 | return CSSValuePool::singleton().createValue(shapeValue->cssBox()); |
2547 | |
2548 | if (shapeValue->type() == ShapeValue::Type::Image) { |
2549 | if (shapeValue->image()) |
2550 | return shapeValue->image()->cssValue(); |
2551 | return CSSValuePool::singleton().createIdentifierValue(CSSValueNone); |
2552 | } |
2553 | |
2554 | ASSERT(shapeValue->type() == ShapeValue::Type::Shape); |
2555 | |
2556 | auto list = CSSValueList::createSpaceSeparated(); |
2557 | list->append(valueForBasicShape(style, *shapeValue->shape())); |
2558 | if (shapeValue->cssBox() != CSSBoxType::BoxMissing) |
2559 | list->append(CSSValuePool::singleton().createValue(shapeValue->cssBox())); |
2560 | return list; |
2561 | } |
2562 | |
2563 | static Ref<CSSValueList> valueForItemPositionWithOverflowAlignment(const StyleSelfAlignmentData& data) |
2564 | { |
2565 | auto& cssValuePool = CSSValuePool::singleton(); |
2566 | auto result = CSSValueList::createSpaceSeparated(); |
2567 | if (data.positionType() == ItemPositionType::Legacy) |
2568 | result->append(cssValuePool.createIdentifierValue(CSSValueLegacy)); |
2569 | if (data.position() == ItemPosition::Baseline) |
2570 | result->append(cssValuePool.createIdentifierValue(CSSValueBaseline)); |
2571 | else if (data.position() == ItemPosition::LastBaseline) { |
2572 | result->append(cssValuePool.createIdentifierValue(CSSValueLast)); |
2573 | result->append(cssValuePool.createIdentifierValue(CSSValueBaseline)); |
2574 | } else { |
2575 | if (data.position() >= ItemPosition::Center && data.overflow() != OverflowAlignment::Default) |
2576 | result->append(cssValuePool.createValue(data.overflow())); |
2577 | if (data.position() == ItemPosition::Legacy) |
2578 | result->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
2579 | else |
2580 | result->append(cssValuePool.createValue(data.position())); |
2581 | } |
2582 | ASSERT(result->length() <= 2); |
2583 | return result; |
2584 | } |
2585 | |
2586 | static Ref<CSSValueList> valueForContentPositionAndDistributionWithOverflowAlignment(const StyleContentAlignmentData& data) |
2587 | { |
2588 | auto& cssValuePool = CSSValuePool::singleton(); |
2589 | auto result = CSSValueList::createSpaceSeparated(); |
2590 | // Handle content-distribution values |
2591 | if (data.distribution() != ContentDistribution::Default) |
2592 | result->append(cssValuePool.createValue(data.distribution())); |
2593 | |
2594 | // Handle content-position values (either as fallback or actual value) |
2595 | switch (data.position()) { |
2596 | case ContentPosition::Normal: |
2597 | // Handle 'normal' value, not valid as content-distribution fallback. |
2598 | if (data.distribution() == ContentDistribution::Default) |
2599 | result->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
2600 | break; |
2601 | case ContentPosition::LastBaseline: |
2602 | result->append(cssValuePool.createIdentifierValue(CSSValueLast)); |
2603 | result->append(cssValuePool.createIdentifierValue(CSSValueBaseline)); |
2604 | break; |
2605 | default: |
2606 | // Handle overflow-alignment (only allowed for content-position values) |
2607 | if ((data.position() >= ContentPosition::Center || data.distribution() != ContentDistribution::Default) && data.overflow() != OverflowAlignment::Default) |
2608 | result->append(cssValuePool.createValue(data.overflow())); |
2609 | result->append(cssValuePool.createValue(data.position())); |
2610 | } |
2611 | |
2612 | ASSERT(result->length() > 0); |
2613 | ASSERT(result->length() <= 3); |
2614 | return result; |
2615 | } |
2616 | |
2617 | static Ref<CSSValue> paintOrder(PaintOrder paintOrder) |
2618 | { |
2619 | if (paintOrder == PaintOrder::Normal) |
2620 | return CSSPrimitiveValue::createIdentifier(CSSValueNormal); |
2621 | |
2622 | auto paintOrderList = CSSValueList::createSpaceSeparated(); |
2623 | switch (paintOrder) { |
2624 | case PaintOrder::Normal: |
2625 | ASSERT_NOT_REACHED(); |
2626 | break; |
2627 | case PaintOrder::Fill: |
2628 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill)); |
2629 | break; |
2630 | case PaintOrder::FillMarkers: |
2631 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueFill)); |
2632 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); |
2633 | break; |
2634 | case PaintOrder::Stroke: |
2635 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); |
2636 | break; |
2637 | case PaintOrder::StrokeMarkers: |
2638 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); |
2639 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); |
2640 | break; |
2641 | case PaintOrder::Markers: |
2642 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); |
2643 | break; |
2644 | case PaintOrder::MarkersStroke: |
2645 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers)); |
2646 | paintOrderList->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke)); |
2647 | break; |
2648 | } |
2649 | return paintOrderList; |
2650 | } |
2651 | |
2652 | inline static bool isFlexOrGrid(ContainerNode* element) |
2653 | { |
2654 | return element && element->computedStyle() && element->computedStyle()->isDisplayFlexibleOrGridBox(); |
2655 | } |
2656 | |
2657 | RefPtr<CSSValue> ComputedStyleExtractor::(const String& propertyName) |
2658 | { |
2659 | Element* styledElement = this->styledElement(); |
2660 | if (!styledElement) |
2661 | return nullptr; |
2662 | |
2663 | if (updateStyleIfNeededForProperty(*styledElement, CSSPropertyCustom)) { |
2664 | // Style update may change styledElement() to PseudoElement or back. |
2665 | styledElement = this->styledElement(); |
2666 | } |
2667 | |
2668 | std::unique_ptr<RenderStyle> ownedStyle; |
2669 | auto* style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, CSSPropertyCustom, ownedStyle); |
2670 | if (!style) |
2671 | return nullptr; |
2672 | |
2673 | auto* registered = styledElement->document().getCSSRegisteredCustomPropertySet().get(propertyName); |
2674 | auto* value = style->getCustomProperty(propertyName); |
2675 | |
2676 | if (registered && !value) |
2677 | return registered->initialValueCopy(); |
2678 | |
2679 | if (!value) |
2680 | return nullptr; |
2681 | |
2682 | return WTF::switchOn(value->value(), [&](const Ref<CSSVariableReferenceValue>&) { |
2683 | ASSERT_NOT_REACHED(); |
2684 | return RefPtr<CSSValue>(); |
2685 | }, [&](const CSSValueID&) { |
2686 | return CSSCustomPropertyValue::create(*value); |
2687 | }, [&](const Ref<CSSVariableData>&) { |
2688 | return CSSCustomPropertyValue::create(*value); |
2689 | }, [&](const Length& value) { |
2690 | return zoomAdjustedPixelValueForLength(value, *style); |
2691 | }, [&](const Ref<StyleImage>&) { |
2692 | return CSSCustomPropertyValue::create(*value); |
2693 | }); |
2694 | } |
2695 | |
2696 | String ComputedStyleExtractor::(const String& propertyName) |
2697 | { |
2698 | RefPtr<CSSValue> propertyValue = customPropertyValue(propertyName); |
2699 | return propertyValue ? propertyValue->cssText() : emptyString(); |
2700 | } |
2701 | |
2702 | static Ref<CSSFontValue> fontShorthandValueForSelectionProperties(const FontDescription& fontDescription) |
2703 | { |
2704 | auto computedFont = CSSFontValue::create(); |
2705 | |
2706 | auto variantCaps = fontDescription.variantCaps(); |
2707 | if (variantCaps == FontVariantCaps::Small) |
2708 | computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueSmallCaps); |
2709 | else if (variantCaps == FontVariantCaps::Normal) |
2710 | computedFont->variant = CSSValuePool::singleton().createIdentifierValue(CSSValueNormal); |
2711 | else |
2712 | return CSSFontValue::create(); |
2713 | |
2714 | auto weight = fontDescription.weight(); |
2715 | if (auto value = fontWeightKeyword(weight)) |
2716 | computedFont->weight = CSSValuePool::singleton().createIdentifierValue(value.value()); |
2717 | else if (isCSS21Weight(weight)) |
2718 | computedFont->weight = CSSValuePool::singleton().createValue(static_cast<float>(weight), CSSPrimitiveValue::CSS_NUMBER); |
2719 | else |
2720 | return CSSFontValue::create(); |
2721 | |
2722 | if (auto keyword = fontStretchKeyword(fontDescription.stretch())) |
2723 | computedFont->stretch = CSSValuePool::singleton().createIdentifierValue(keyword.value()); |
2724 | else |
2725 | return CSSFontValue::create(); |
2726 | |
2727 | if (auto italic = fontStyleKeyword(fontDescription.italic(), fontDescription.fontStyleAxis())) |
2728 | computedFont->style = CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(italic.value())); |
2729 | else |
2730 | return CSSFontValue::create(); |
2731 | |
2732 | return computedFont; |
2733 | } |
2734 | |
2735 | RefPtr<CSSValue> ComputedStyleExtractor::(CSSPropertyID propertyID, EUpdateLayout updateLayout) |
2736 | { |
2737 | auto* styledElement = this->styledElement(); |
2738 | if (!styledElement) |
2739 | return nullptr; |
2740 | |
2741 | std::unique_ptr<RenderStyle> ownedStyle; |
2742 | const RenderStyle* style = nullptr; |
2743 | RenderElement* renderer = nullptr; |
2744 | bool forceFullLayout = false; |
2745 | if (updateLayout) { |
2746 | Document& document = m_element->document(); |
2747 | |
2748 | if (updateStyleIfNeededForProperty(*styledElement, propertyID)) { |
2749 | // Style update may change styledElement() to PseudoElement or back. |
2750 | styledElement = this->styledElement(); |
2751 | } |
2752 | renderer = styledRenderer(); |
2753 | |
2754 | if (propertyID == CSSPropertyDisplay && !renderer && is<SVGElement>(*styledElement) && !downcast<SVGElement>(*styledElement).isValid()) |
2755 | return nullptr; |
2756 | |
2757 | style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle); |
2758 | |
2759 | // FIXME: Some of these cases could be narrowed down or optimized better. |
2760 | forceFullLayout = isLayoutDependent(propertyID, style, renderer) |
2761 | || styledElement->isInShadowTree() |
2762 | || (document.styleScope().resolverIfExists() && document.styleScope().resolverIfExists()->hasViewportDependentMediaQueries() && document.ownerElement()); |
2763 | |
2764 | if (forceFullLayout) { |
2765 | document.updateLayoutIgnorePendingStylesheets(); |
2766 | styledElement = this->styledElement(); |
2767 | } |
2768 | } |
2769 | |
2770 | if (!updateLayout || forceFullLayout) { |
2771 | style = computeRenderStyleForProperty(*styledElement, m_pseudoElementSpecifier, propertyID, ownedStyle); |
2772 | renderer = styledRenderer(); |
2773 | } |
2774 | |
2775 | if (!style) |
2776 | return nullptr; |
2777 | |
2778 | return valueForPropertyInStyle(*style, propertyID, renderer); |
2779 | } |
2780 | |
2781 | RefPtr<CSSValue> ComputedStyleExtractor::(const RenderStyle& style, CSSPropertyID propertyID, RenderElement* renderer) |
2782 | { |
2783 | auto& cssValuePool = CSSValuePool::singleton(); |
2784 | propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style.direction(), style.writingMode()); |
2785 | |
2786 | switch (propertyID) { |
2787 | case CSSPropertyInvalid: |
2788 | #if ENABLE(TEXT_AUTOSIZING) |
2789 | case CSSPropertyInternalTextAutosizingStatus: |
2790 | #endif |
2791 | break; |
2792 | |
2793 | case CSSPropertyBackgroundColor: |
2794 | return cssValuePool.createColorValue(m_allowVisitedStyle? style.visitedDependentColor(CSSPropertyBackgroundColor) : style.backgroundColor()); |
2795 | case CSSPropertyBackgroundImage: |
2796 | case CSSPropertyWebkitMaskImage: { |
2797 | auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style.maskLayers() : style.backgroundLayers(); |
2798 | if (!layers.next()) { |
2799 | if (layers.image()) |
2800 | return layers.image()->cssValue(); |
2801 | return cssValuePool.createIdentifierValue(CSSValueNone); |
2802 | } |
2803 | auto list = CSSValueList::createCommaSeparated(); |
2804 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) { |
2805 | if (currLayer->image()) |
2806 | list->append(currLayer->image()->cssValue()); |
2807 | else |
2808 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
2809 | } |
2810 | return list; |
2811 | } |
2812 | case CSSPropertyBackgroundSize: |
2813 | case CSSPropertyWebkitBackgroundSize: |
2814 | case CSSPropertyWebkitMaskSize: { |
2815 | auto& layers = propertyID == CSSPropertyWebkitMaskSize ? style.maskLayers() : style.backgroundLayers(); |
2816 | if (!layers.next()) |
2817 | return fillSizeToCSSValue(layers.size(), style); |
2818 | auto list = CSSValueList::createCommaSeparated(); |
2819 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2820 | list->append(fillSizeToCSSValue(currLayer->size(), style)); |
2821 | return list; |
2822 | } |
2823 | case CSSPropertyBackgroundRepeat: |
2824 | case CSSPropertyWebkitMaskRepeat: { |
2825 | auto& layers = propertyID == CSSPropertyWebkitMaskRepeat ? style.maskLayers() : style.backgroundLayers(); |
2826 | if (!layers.next()) |
2827 | return fillRepeatToCSSValue(layers.repeatX(), layers.repeatY()); |
2828 | auto list = CSSValueList::createCommaSeparated(); |
2829 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2830 | list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); |
2831 | return list; |
2832 | } |
2833 | case CSSPropertyWebkitMaskSourceType: { |
2834 | auto& layers = style.maskLayers(); |
2835 | if (!layers.next()) |
2836 | return fillSourceTypeToCSSValue(layers.maskSourceType()); |
2837 | auto list = CSSValueList::createCommaSeparated(); |
2838 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2839 | list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType())); |
2840 | return list; |
2841 | } |
2842 | case CSSPropertyWebkitBackgroundComposite: |
2843 | case CSSPropertyWebkitMaskComposite: { |
2844 | auto& layers = propertyID == CSSPropertyWebkitMaskComposite ? style.maskLayers() : style.backgroundLayers(); |
2845 | if (!layers.next()) |
2846 | return cssValuePool.createValue(layers.composite()); |
2847 | auto list = CSSValueList::createCommaSeparated(); |
2848 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2849 | list->append(cssValuePool.createValue(currLayer->composite())); |
2850 | return list; |
2851 | } |
2852 | case CSSPropertyBackgroundAttachment: { |
2853 | auto& layers = style.backgroundLayers(); |
2854 | if (!layers.next()) |
2855 | return cssValuePool.createValue(layers.attachment()); |
2856 | auto list = CSSValueList::createCommaSeparated(); |
2857 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2858 | list->append(cssValuePool.createValue(currLayer->attachment())); |
2859 | return list; |
2860 | } |
2861 | case CSSPropertyBackgroundClip: |
2862 | case CSSPropertyBackgroundOrigin: |
2863 | case CSSPropertyWebkitBackgroundClip: |
2864 | case CSSPropertyWebkitBackgroundOrigin: |
2865 | case CSSPropertyWebkitMaskClip: |
2866 | case CSSPropertyWebkitMaskOrigin: { |
2867 | auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style.maskLayers() : style.backgroundLayers(); |
2868 | bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; |
2869 | if (!layers.next()) |
2870 | return cssValuePool.createValue(isClip ? layers.clip() : layers.origin()); |
2871 | auto list = CSSValueList::createCommaSeparated(); |
2872 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2873 | list->append(cssValuePool.createValue(isClip ? currLayer->clip() : currLayer->origin())); |
2874 | return list; |
2875 | } |
2876 | case CSSPropertyBackgroundPosition: |
2877 | case CSSPropertyWebkitMaskPosition: { |
2878 | auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style.maskLayers() : style.backgroundLayers(); |
2879 | if (!layers.next()) |
2880 | return createPositionListForLayer(propertyID, layers, style); |
2881 | |
2882 | auto list = CSSValueList::createCommaSeparated(); |
2883 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2884 | list->append(createPositionListForLayer(propertyID, *currLayer, style)); |
2885 | return list; |
2886 | } |
2887 | case CSSPropertyBackgroundPositionX: |
2888 | case CSSPropertyWebkitMaskPositionX: { |
2889 | auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style.maskLayers() : style.backgroundLayers(); |
2890 | if (!layers.next()) |
2891 | return cssValuePool.createValue(layers.xPosition()); |
2892 | |
2893 | auto list = CSSValueList::createCommaSeparated(); |
2894 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2895 | list->append(cssValuePool.createValue(currLayer->xPosition())); |
2896 | |
2897 | return list; |
2898 | } |
2899 | case CSSPropertyBackgroundPositionY: |
2900 | case CSSPropertyWebkitMaskPositionY: { |
2901 | auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style.maskLayers() : style.backgroundLayers(); |
2902 | if (!layers.next()) |
2903 | return cssValuePool.createValue(layers.yPosition()); |
2904 | |
2905 | auto list = CSSValueList::createCommaSeparated(); |
2906 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2907 | list->append(cssValuePool.createValue(currLayer->yPosition())); |
2908 | |
2909 | return list; |
2910 | } |
2911 | case CSSPropertyBorderCollapse: |
2912 | if (style.borderCollapse() == BorderCollapse::Collapse) |
2913 | return cssValuePool.createIdentifierValue(CSSValueCollapse); |
2914 | return cssValuePool.createIdentifierValue(CSSValueSeparate); |
2915 | case CSSPropertyBorderSpacing: { |
2916 | auto list = CSSValueList::createSpaceSeparated(); |
2917 | list->append(zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style)); |
2918 | list->append(zoomAdjustedPixelValue(style.verticalBorderSpacing(), style)); |
2919 | return list; |
2920 | } |
2921 | case CSSPropertyWebkitBorderHorizontalSpacing: |
2922 | return zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style); |
2923 | case CSSPropertyWebkitBorderVerticalSpacing: |
2924 | return zoomAdjustedPixelValue(style.verticalBorderSpacing(), style); |
2925 | case CSSPropertyBorderImageSource: |
2926 | if (style.borderImageSource()) |
2927 | return style.borderImageSource()->cssValue(); |
2928 | return cssValuePool.createIdentifierValue(CSSValueNone); |
2929 | case CSSPropertyBorderTopColor: |
2930 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(&style, style.borderTopColor()); |
2931 | case CSSPropertyBorderRightColor: |
2932 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(&style, style.borderRightColor()); |
2933 | case CSSPropertyBorderBottomColor: |
2934 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(&style, style.borderBottomColor()); |
2935 | case CSSPropertyBorderLeftColor: |
2936 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(&style, style.borderLeftColor()); |
2937 | case CSSPropertyBorderTopStyle: |
2938 | return cssValuePool.createValue(style.borderTopStyle()); |
2939 | case CSSPropertyBorderRightStyle: |
2940 | return cssValuePool.createValue(style.borderRightStyle()); |
2941 | case CSSPropertyBorderBottomStyle: |
2942 | return cssValuePool.createValue(style.borderBottomStyle()); |
2943 | case CSSPropertyBorderLeftStyle: |
2944 | return cssValuePool.createValue(style.borderLeftStyle()); |
2945 | case CSSPropertyBorderTopWidth: |
2946 | return zoomAdjustedPixelValue(style.borderTopWidth(), style); |
2947 | case CSSPropertyBorderRightWidth: |
2948 | return zoomAdjustedPixelValue(style.borderRightWidth(), style); |
2949 | case CSSPropertyBorderBottomWidth: |
2950 | return zoomAdjustedPixelValue(style.borderBottomWidth(), style); |
2951 | case CSSPropertyBorderLeftWidth: |
2952 | return zoomAdjustedPixelValue(style.borderLeftWidth(), style); |
2953 | case CSSPropertyBottom: |
2954 | return positionOffsetValue(style, CSSPropertyBottom, renderer); |
2955 | case CSSPropertyWebkitBoxAlign: |
2956 | return cssValuePool.createValue(style.boxAlign()); |
2957 | #if ENABLE(CSS_BOX_DECORATION_BREAK) |
2958 | case CSSPropertyWebkitBoxDecorationBreak: |
2959 | if (style.boxDecorationBreak() == BoxDecorationBreak::Slice) |
2960 | return cssValuePool.createIdentifierValue(CSSValueSlice); |
2961 | return cssValuePool.createIdentifierValue(CSSValueClone); |
2962 | #endif |
2963 | case CSSPropertyWebkitBoxDirection: |
2964 | return cssValuePool.createValue(style.boxDirection()); |
2965 | case CSSPropertyWebkitBoxFlex: |
2966 | return cssValuePool.createValue(style.boxFlex(), CSSPrimitiveValue::CSS_NUMBER); |
2967 | case CSSPropertyWebkitBoxFlexGroup: |
2968 | return cssValuePool.createValue(style.boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); |
2969 | case CSSPropertyWebkitBoxLines: |
2970 | return cssValuePool.createValue(style.boxLines()); |
2971 | case CSSPropertyWebkitBoxOrdinalGroup: |
2972 | return cssValuePool.createValue(style.boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); |
2973 | case CSSPropertyWebkitBoxOrient: |
2974 | return cssValuePool.createValue(style.boxOrient()); |
2975 | case CSSPropertyWebkitBoxPack: |
2976 | return cssValuePool.createValue(style.boxPack()); |
2977 | case CSSPropertyWebkitBoxReflect: |
2978 | return valueForReflection(style.boxReflect(), style); |
2979 | case CSSPropertyBoxShadow: |
2980 | case CSSPropertyWebkitBoxShadow: |
2981 | return valueForShadow(style.boxShadow(), propertyID, style); |
2982 | case CSSPropertyCaptionSide: |
2983 | return cssValuePool.createValue(style.captionSide()); |
2984 | case CSSPropertyCaretColor: |
2985 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(&style, style.caretColor()); |
2986 | case CSSPropertyClear: |
2987 | return cssValuePool.createValue(style.clear()); |
2988 | case CSSPropertyColor: |
2989 | return cssValuePool.createColorValue(m_allowVisitedStyle ? style.visitedDependentColor(CSSPropertyColor) : style.color()); |
2990 | case CSSPropertyWebkitPrintColorAdjust: |
2991 | return cssValuePool.createValue(style.printColorAdjust()); |
2992 | case CSSPropertyWebkitColumnAxis: |
2993 | return cssValuePool.createValue(style.columnAxis()); |
2994 | case CSSPropertyColumnCount: |
2995 | if (style.hasAutoColumnCount()) |
2996 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
2997 | return cssValuePool.createValue(style.columnCount(), CSSPrimitiveValue::CSS_NUMBER); |
2998 | case CSSPropertyColumnFill: |
2999 | return cssValuePool.createValue(style.columnFill()); |
3000 | case CSSPropertyColumnGap: |
3001 | if (style.columnGap().isNormal()) |
3002 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3003 | return zoomAdjustedPixelValueForLength(style.columnGap().length(), style); |
3004 | case CSSPropertyRowGap: |
3005 | if (style.rowGap().isNormal()) |
3006 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3007 | return zoomAdjustedPixelValueForLength(style.rowGap().length(), style); |
3008 | case CSSPropertyWebkitColumnProgression: |
3009 | return cssValuePool.createValue(style.columnProgression()); |
3010 | case CSSPropertyColumnRuleColor: |
3011 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.columnRuleColor()); |
3012 | case CSSPropertyColumnRuleStyle: |
3013 | return cssValuePool.createValue(style.columnRuleStyle()); |
3014 | case CSSPropertyColumnRuleWidth: |
3015 | return zoomAdjustedPixelValue(style.columnRuleWidth(), style); |
3016 | case CSSPropertyColumnSpan: |
3017 | return cssValuePool.createIdentifierValue(style.columnSpan() == ColumnSpan::All ? CSSValueAll : CSSValueNone); |
3018 | case CSSPropertyWebkitColumnBreakAfter: |
3019 | return cssValuePool.createValue(convertToColumnBreak(style.breakAfter())); |
3020 | case CSSPropertyWebkitColumnBreakBefore: |
3021 | return cssValuePool.createValue(convertToColumnBreak(style.breakBefore())); |
3022 | case CSSPropertyWebkitColumnBreakInside: |
3023 | return cssValuePool.createValue(convertToColumnBreak(style.breakInside())); |
3024 | case CSSPropertyColumnWidth: |
3025 | if (style.hasAutoColumnWidth()) |
3026 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3027 | return zoomAdjustedPixelValue(style.columnWidth(), style); |
3028 | case CSSPropertyTabSize: |
3029 | return cssValuePool.createValue(style.tabSize().widthInPixels(1.0), style.tabSize().isSpaces() ? CSSPrimitiveValue::CSS_NUMBER : CSSPrimitiveValue::CSS_PX); |
3030 | case CSSPropertyCursor: { |
3031 | RefPtr<CSSValueList> list; |
3032 | auto* cursors = style.cursors(); |
3033 | if (cursors && cursors->size() > 0) { |
3034 | list = CSSValueList::createCommaSeparated(); |
3035 | for (unsigned i = 0; i < cursors->size(); ++i) |
3036 | if (StyleImage* image = cursors->at(i).image()) |
3037 | list->append(image->cssValue()); |
3038 | } |
3039 | auto value = cssValuePool.createValue(style.cursor()); |
3040 | if (list) { |
3041 | list->append(WTFMove(value)); |
3042 | return list; |
3043 | } |
3044 | return value; |
3045 | } |
3046 | #if ENABLE(CURSOR_VISIBILITY) |
3047 | case CSSPropertyWebkitCursorVisibility: |
3048 | return cssValuePool.createValue(style.cursorVisibility()); |
3049 | #endif |
3050 | case CSSPropertyDirection: |
3051 | return cssValuePool.createValue(style.direction()); |
3052 | case CSSPropertyDisplay: |
3053 | return cssValuePool.createValue(style.display()); |
3054 | case CSSPropertyEmptyCells: |
3055 | return cssValuePool.createValue(style.emptyCells()); |
3056 | case CSSPropertyAlignContent: |
3057 | return valueForContentPositionAndDistributionWithOverflowAlignment(style.alignContent()); |
3058 | case CSSPropertyAlignItems: |
3059 | return valueForItemPositionWithOverflowAlignment(style.alignItems()); |
3060 | case CSSPropertyAlignSelf: |
3061 | return valueForItemPositionWithOverflowAlignment(style.alignSelf()); |
3062 | case CSSPropertyFlex: |
3063 | return getCSSPropertyValuesForShorthandProperties(flexShorthand()); |
3064 | case CSSPropertyFlexBasis: |
3065 | return cssValuePool.createValue(style.flexBasis(), style); |
3066 | case CSSPropertyFlexDirection: |
3067 | return cssValuePool.createValue(style.flexDirection()); |
3068 | case CSSPropertyFlexFlow: |
3069 | return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand()); |
3070 | case CSSPropertyFlexGrow: |
3071 | return cssValuePool.createValue(style.flexGrow()); |
3072 | case CSSPropertyFlexShrink: |
3073 | return cssValuePool.createValue(style.flexShrink()); |
3074 | case CSSPropertyFlexWrap: |
3075 | return cssValuePool.createValue(style.flexWrap()); |
3076 | case CSSPropertyJustifyContent: |
3077 | return valueForContentPositionAndDistributionWithOverflowAlignment(style.justifyContent()); |
3078 | case CSSPropertyJustifyItems: |
3079 | return valueForItemPositionWithOverflowAlignment(style.justifyItems()); |
3080 | case CSSPropertyJustifySelf: |
3081 | return valueForItemPositionWithOverflowAlignment(style.justifySelf()); |
3082 | case CSSPropertyPlaceContent: |
3083 | return getCSSPropertyValuesForShorthandProperties(placeContentShorthand()); |
3084 | case CSSPropertyPlaceItems: |
3085 | return getCSSPropertyValuesForShorthandProperties(placeItemsShorthand()); |
3086 | case CSSPropertyPlaceSelf: |
3087 | return getCSSPropertyValuesForShorthandProperties(placeSelfShorthand()); |
3088 | case CSSPropertyOrder: |
3089 | return cssValuePool.createValue(style.order(), CSSPrimitiveValue::CSS_NUMBER); |
3090 | case CSSPropertyFloat: |
3091 | if (style.display() != DisplayType::None && style.hasOutOfFlowPosition()) |
3092 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3093 | return cssValuePool.createValue(style.floating()); |
3094 | case CSSPropertyFont: { |
3095 | auto computedFont = fontShorthandValueForSelectionProperties(style.fontDescription()); |
3096 | computedFont->size = fontSizeFromStyle(style); |
3097 | computedFont->lineHeight = lineHeightFromStyle(style); |
3098 | computedFont->family = fontFamilyListFromStyle(style); |
3099 | return computedFont; |
3100 | } |
3101 | case CSSPropertyFontFamily: |
3102 | return fontFamilyFromStyle(style); |
3103 | case CSSPropertyFontSize: |
3104 | return fontSizeFromStyle(style); |
3105 | case CSSPropertyFontStyle: |
3106 | return fontStyleFromStyle(style); |
3107 | case CSSPropertyFontStretch: |
3108 | return fontStretchFromStyle(style); |
3109 | case CSSPropertyFontVariant: |
3110 | return fontVariantFromStyle(style); |
3111 | case CSSPropertyFontWeight: |
3112 | return fontWeightFromStyle(style); |
3113 | case CSSPropertyFontSynthesis: |
3114 | return fontSynthesisFromStyle(style); |
3115 | case CSSPropertyFontFeatureSettings: { |
3116 | const FontFeatureSettings& featureSettings = style.fontDescription().featureSettings(); |
3117 | if (!featureSettings.size()) |
3118 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3119 | auto list = CSSValueList::createCommaSeparated(); |
3120 | for (auto& feature : featureSettings) |
3121 | list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value())); |
3122 | return list; |
3123 | } |
3124 | #if ENABLE(VARIATION_FONTS) |
3125 | case CSSPropertyFontVariationSettings: { |
3126 | const FontVariationSettings& variationSettings = style.fontDescription().variationSettings(); |
3127 | if (variationSettings.isEmpty()) |
3128 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3129 | auto list = CSSValueList::createCommaSeparated(); |
3130 | for (auto& feature : variationSettings) |
3131 | list->append(CSSFontVariationValue::create(feature.tag(), feature.value())); |
3132 | return list; |
3133 | } |
3134 | case CSSPropertyFontOpticalSizing: |
3135 | return cssValuePool.createValue(style.fontDescription().opticalSizing()); |
3136 | #endif |
3137 | case CSSPropertyGridAutoFlow: { |
3138 | auto list = CSSValueList::createSpaceSeparated(); |
3139 | ASSERT(style.isGridAutoFlowDirectionRow() || style.isGridAutoFlowDirectionColumn()); |
3140 | if (style.isGridAutoFlowDirectionRow()) |
3141 | list->append(cssValuePool.createIdentifierValue(CSSValueRow)); |
3142 | else |
3143 | list->append(cssValuePool.createIdentifierValue(CSSValueColumn)); |
3144 | |
3145 | if (style.isGridAutoFlowAlgorithmDense()) |
3146 | list->append(cssValuePool.createIdentifierValue(CSSValueDense)); |
3147 | |
3148 | return list; |
3149 | } |
3150 | |
3151 | // Specs mention that getComputedStyle() should return the used value of the property instead of the computed |
3152 | // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like |
3153 | // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things |
3154 | // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See |
3155 | // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html |
3156 | case CSSPropertyGridAutoColumns: |
3157 | return valueForGridTrackSizeList(ForColumns, style); |
3158 | case CSSPropertyGridAutoRows: |
3159 | return valueForGridTrackSizeList(ForRows, style); |
3160 | |
3161 | case CSSPropertyGridTemplateColumns: |
3162 | return valueForGridTrackList(ForColumns, renderer, style); |
3163 | case CSSPropertyGridTemplateRows: |
3164 | return valueForGridTrackList(ForRows, renderer, style); |
3165 | |
3166 | case CSSPropertyGridColumnStart: |
3167 | return valueForGridPosition(style.gridItemColumnStart()); |
3168 | case CSSPropertyGridColumnEnd: |
3169 | return valueForGridPosition(style.gridItemColumnEnd()); |
3170 | case CSSPropertyGridRowStart: |
3171 | return valueForGridPosition(style.gridItemRowStart()); |
3172 | case CSSPropertyGridRowEnd: |
3173 | return valueForGridPosition(style.gridItemRowEnd()); |
3174 | case CSSPropertyGridArea: |
3175 | return getCSSPropertyValuesForGridShorthand(gridAreaShorthand()); |
3176 | case CSSPropertyGridTemplate: |
3177 | return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand()); |
3178 | case CSSPropertyGrid: |
3179 | return getCSSPropertyValuesForGridShorthand(gridShorthand()); |
3180 | case CSSPropertyGridColumn: |
3181 | return getCSSPropertyValuesForGridShorthand(gridColumnShorthand()); |
3182 | case CSSPropertyGridRow: |
3183 | return getCSSPropertyValuesForGridShorthand(gridRowShorthand()); |
3184 | case CSSPropertyGridTemplateAreas: |
3185 | if (!style.namedGridAreaRowCount()) { |
3186 | ASSERT(!style.namedGridAreaColumnCount()); |
3187 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3188 | } |
3189 | return CSSGridTemplateAreasValue::create(style.namedGridArea(), style.namedGridAreaRowCount(), style.namedGridAreaColumnCount()); |
3190 | case CSSPropertyGap: |
3191 | return getCSSPropertyValuesForShorthandProperties(gapShorthand()); |
3192 | case CSSPropertyHeight: |
3193 | if (renderer && !renderer->isRenderSVGModelObject()) { |
3194 | // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property, |
3195 | // the "height" property does not apply for non-replaced inline elements. |
3196 | if (!isNonReplacedInline(*renderer)) |
3197 | return zoomAdjustedPixelValue(sizingBox(*renderer).height(), style); |
3198 | } |
3199 | return zoomAdjustedPixelValueForLength(style.height(), style); |
3200 | case CSSPropertyWebkitHyphens: |
3201 | return cssValuePool.createValue(style.hyphens()); |
3202 | case CSSPropertyWebkitHyphenateCharacter: |
3203 | if (style.hyphenationString().isNull()) |
3204 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3205 | return cssValuePool.createValue(style.hyphenationString(), CSSPrimitiveValue::CSS_STRING); |
3206 | case CSSPropertyWebkitHyphenateLimitAfter: |
3207 | if (style.hyphenationLimitAfter() < 0) |
3208 | return CSSPrimitiveValue::createIdentifier(CSSValueAuto); |
3209 | return CSSPrimitiveValue::create(style.hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER); |
3210 | case CSSPropertyWebkitHyphenateLimitBefore: |
3211 | if (style.hyphenationLimitBefore() < 0) |
3212 | return CSSPrimitiveValue::createIdentifier(CSSValueAuto); |
3213 | return CSSPrimitiveValue::create(style.hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER); |
3214 | case CSSPropertyWebkitHyphenateLimitLines: |
3215 | if (style.hyphenationLimitLines() < 0) |
3216 | return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit); |
3217 | return CSSPrimitiveValue::create(style.hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER); |
3218 | case CSSPropertyWebkitBorderFit: |
3219 | if (style.borderFit() == BorderFit::Border) |
3220 | return cssValuePool.createIdentifierValue(CSSValueBorder); |
3221 | return cssValuePool.createIdentifierValue(CSSValueLines); |
3222 | #if ENABLE(CSS_IMAGE_ORIENTATION) |
3223 | case CSSPropertyImageOrientation: |
3224 | return cssValuePool.createValue(style.imageOrientation()); |
3225 | #endif |
3226 | case CSSPropertyImageRendering: |
3227 | return CSSPrimitiveValue::create(style.imageRendering()); |
3228 | #if ENABLE(CSS_IMAGE_RESOLUTION) |
3229 | case CSSPropertyImageResolution: |
3230 | return cssValuePool.createValue(style.imageResolution(), CSSPrimitiveValue::CSS_DPPX); |
3231 | #endif |
3232 | case CSSPropertyLeft: |
3233 | return positionOffsetValue(style, CSSPropertyLeft, renderer); |
3234 | case CSSPropertyLetterSpacing: |
3235 | if (!style.letterSpacing()) |
3236 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3237 | return zoomAdjustedPixelValue(style.letterSpacing(), style); |
3238 | case CSSPropertyWebkitLineClamp: |
3239 | if (style.lineClamp().isNone()) |
3240 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3241 | return cssValuePool.createValue(style.lineClamp().value(), style.lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); |
3242 | case CSSPropertyLineHeight: |
3243 | return lineHeightFromStyle(style); |
3244 | case CSSPropertyListStyleImage: |
3245 | if (style.listStyleImage()) |
3246 | return style.listStyleImage()->cssValue(); |
3247 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3248 | case CSSPropertyListStylePosition: |
3249 | return cssValuePool.createValue(style.listStylePosition()); |
3250 | case CSSPropertyListStyleType: |
3251 | return cssValuePool.createValue(style.listStyleType()); |
3252 | case CSSPropertyWebkitLocale: |
3253 | if (style.locale().isNull()) |
3254 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3255 | return cssValuePool.createValue(style.locale(), CSSPrimitiveValue::CSS_STRING); |
3256 | case CSSPropertyMarginTop: |
3257 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(style, renderer); |
3258 | case CSSPropertyMarginRight: { |
3259 | Length marginRight = style.marginRight(); |
3260 | if (marginRight.isFixed() || !is<RenderBox>(renderer)) |
3261 | return zoomAdjustedPixelValueForLength(marginRight, style); |
3262 | float value; |
3263 | if (marginRight.isPercentOrCalculated()) { |
3264 | // RenderBox gives a marginRight() that is the distance between the right-edge of the child box |
3265 | // and the right-edge of the containing box, when display == DisplayType::Block. Let's calculate the absolute |
3266 | // value of the specified margin-right % instead of relying on RenderBox's marginRight() value. |
3267 | value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent()); |
3268 | } else |
3269 | value = downcast<RenderBox>(*renderer).marginRight(); |
3270 | return zoomAdjustedPixelValue(value, style); |
3271 | } |
3272 | case CSSPropertyMarginBottom: |
3273 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(style, renderer); |
3274 | case CSSPropertyMarginLeft: |
3275 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(style, renderer); |
3276 | case CSSPropertyWebkitMarqueeDirection: |
3277 | return cssValuePool.createValue(style.marqueeDirection()); |
3278 | case CSSPropertyWebkitMarqueeIncrement: |
3279 | return cssValuePool.createValue(style.marqueeIncrement()); |
3280 | case CSSPropertyWebkitMarqueeRepetition: |
3281 | if (style.marqueeLoopCount() < 0) |
3282 | return cssValuePool.createIdentifierValue(CSSValueInfinite); |
3283 | return cssValuePool.createValue(style.marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); |
3284 | case CSSPropertyWebkitMarqueeStyle: |
3285 | return cssValuePool.createValue(style.marqueeBehavior()); |
3286 | case CSSPropertyWebkitUserModify: |
3287 | return cssValuePool.createValue(style.userModify()); |
3288 | case CSSPropertyMaxHeight: { |
3289 | const Length& maxHeight = style.maxHeight(); |
3290 | if (maxHeight.isUndefined()) |
3291 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3292 | return zoomAdjustedPixelValueForLength(maxHeight, style); |
3293 | } |
3294 | case CSSPropertyMaxWidth: { |
3295 | const Length& maxWidth = style.maxWidth(); |
3296 | if (maxWidth.isUndefined()) |
3297 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3298 | return zoomAdjustedPixelValueForLength(maxWidth, style); |
3299 | } |
3300 | case CSSPropertyMinHeight: |
3301 | if (style.minHeight().isAuto()) { |
3302 | auto* styledElement = this->styledElement(); |
3303 | if (styledElement && isFlexOrGrid(styledElement->parentNode())) |
3304 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3305 | return zoomAdjustedPixelValue(0, style); |
3306 | } |
3307 | return zoomAdjustedPixelValueForLength(style.minHeight(), style); |
3308 | case CSSPropertyMinWidth: |
3309 | if (style.minWidth().isAuto()) { |
3310 | auto* styledElement = this->styledElement(); |
3311 | if (styledElement && isFlexOrGrid(styledElement->parentNode())) |
3312 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3313 | return zoomAdjustedPixelValue(0, style); |
3314 | } |
3315 | return zoomAdjustedPixelValueForLength(style.minWidth(), style); |
3316 | case CSSPropertyObjectFit: |
3317 | return cssValuePool.createValue(style.objectFit()); |
3318 | case CSSPropertyObjectPosition: { |
3319 | auto list = CSSValueList::createSpaceSeparated(); |
3320 | list->append(zoomAdjustedPixelValueForLength(style.objectPosition().x(), style)); |
3321 | list->append(zoomAdjustedPixelValueForLength(style.objectPosition().y(), style)); |
3322 | return list; |
3323 | } |
3324 | case CSSPropertyOpacity: |
3325 | return cssValuePool.createValue(style.opacity(), CSSPrimitiveValue::CSS_NUMBER); |
3326 | case CSSPropertyOrphans: |
3327 | if (style.hasAutoOrphans()) |
3328 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3329 | return cssValuePool.createValue(style.orphans(), CSSPrimitiveValue::CSS_NUMBER); |
3330 | case CSSPropertyOutlineColor: |
3331 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.outlineColor()); |
3332 | case CSSPropertyOutlineOffset: |
3333 | return zoomAdjustedPixelValue(style.outlineOffset(), style); |
3334 | case CSSPropertyOutlineStyle: |
3335 | if (style.outlineStyleIsAuto() == OutlineIsAuto::On) |
3336 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3337 | return cssValuePool.createValue(style.outlineStyle()); |
3338 | case CSSPropertyOutlineWidth: |
3339 | return zoomAdjustedPixelValue(style.outlineWidth(), style); |
3340 | case CSSPropertyOverflow: |
3341 | return cssValuePool.createValue(std::max(style.overflowX(), style.overflowY())); |
3342 | case CSSPropertyOverflowWrap: |
3343 | return cssValuePool.createValue(style.overflowWrap()); |
3344 | case CSSPropertyOverflowX: |
3345 | return cssValuePool.createValue(style.overflowX()); |
3346 | case CSSPropertyOverflowY: |
3347 | return cssValuePool.createValue(style.overflowY()); |
3348 | case CSSPropertyPaddingTop: |
3349 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(style, renderer); |
3350 | case CSSPropertyPaddingRight: |
3351 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(style, renderer); |
3352 | case CSSPropertyPaddingBottom: |
3353 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(style, renderer); |
3354 | case CSSPropertyPaddingLeft: |
3355 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(style, renderer); |
3356 | case CSSPropertyPageBreakAfter: |
3357 | return cssValuePool.createValue(convertToPageBreak(style.breakAfter())); |
3358 | case CSSPropertyPageBreakBefore: |
3359 | return cssValuePool.createValue(convertToPageBreak(style.breakBefore())); |
3360 | case CSSPropertyPageBreakInside: |
3361 | return cssValuePool.createValue(convertToPageBreak(style.breakInside())); |
3362 | case CSSPropertyBreakAfter: |
3363 | return cssValuePool.createValue(style.breakAfter()); |
3364 | case CSSPropertyBreakBefore: |
3365 | return cssValuePool.createValue(style.breakBefore()); |
3366 | case CSSPropertyBreakInside: |
3367 | return cssValuePool.createValue(style.breakInside()); |
3368 | case CSSPropertyHangingPunctuation: |
3369 | return hangingPunctuationToCSSValue(style.hangingPunctuation()); |
3370 | case CSSPropertyPosition: |
3371 | return cssValuePool.createValue(style.position()); |
3372 | case CSSPropertyRight: |
3373 | return positionOffsetValue(style, CSSPropertyRight, renderer); |
3374 | case CSSPropertyWebkitRubyPosition: |
3375 | return cssValuePool.createValue(style.rubyPosition()); |
3376 | case CSSPropertyTableLayout: |
3377 | return cssValuePool.createValue(style.tableLayout()); |
3378 | case CSSPropertyTextAlign: |
3379 | return cssValuePool.createValue(style.textAlign()); |
3380 | case CSSPropertyTextDecoration: |
3381 | return renderTextDecorationFlagsToCSSValue(style.textDecoration()); |
3382 | #if ENABLE(CSS3_TEXT) |
3383 | case CSSPropertyWebkitTextAlignLast: |
3384 | return cssValuePool.createValue(style.textAlignLast()); |
3385 | case CSSPropertyWebkitTextJustify: |
3386 | return cssValuePool.createValue(style.textJustify()); |
3387 | #endif // CSS3_TEXT |
3388 | case CSSPropertyWebkitTextDecoration: |
3389 | return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand()); |
3390 | case CSSPropertyTextDecorationLine: |
3391 | return renderTextDecorationFlagsToCSSValue(style.textDecoration()); |
3392 | case CSSPropertyTextDecorationStyle: |
3393 | return renderTextDecorationStyleFlagsToCSSValue(style.textDecorationStyle()); |
3394 | case CSSPropertyTextDecorationColor: |
3395 | return currentColorOrValidColor(&style, style.textDecorationColor()); |
3396 | case CSSPropertyTextDecorationSkip: |
3397 | return renderTextDecorationSkipFlagsToCSSValue(style.textDecorationSkip()); |
3398 | case CSSPropertyTextUnderlinePosition: |
3399 | return cssValuePool.createValue(style.textUnderlinePosition()); |
3400 | case CSSPropertyTextUnderlineOffset: |
3401 | return textUnderlineOffsetToCSSValue(style.textUnderlineOffset()); |
3402 | case CSSPropertyTextDecorationThickness: |
3403 | return textDecorationThicknessToCSSValue(style.textDecorationThickness()); |
3404 | case CSSPropertyWebkitTextDecorationsInEffect: |
3405 | return renderTextDecorationFlagsToCSSValue(style.textDecorationsInEffect()); |
3406 | case CSSPropertyWebkitTextFillColor: |
3407 | return currentColorOrValidColor(&style, style.textFillColor()); |
3408 | case CSSPropertyWebkitTextEmphasisColor: |
3409 | return currentColorOrValidColor(&style, style.textEmphasisColor()); |
3410 | case CSSPropertyWebkitTextEmphasisPosition: |
3411 | return renderEmphasisPositionFlagsToCSSValue(style.textEmphasisPosition()); |
3412 | case CSSPropertyWebkitTextEmphasisStyle: |
3413 | switch (style.textEmphasisMark()) { |
3414 | case TextEmphasisMark::None: |
3415 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3416 | case TextEmphasisMark::Custom: |
3417 | return cssValuePool.createValue(style.textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); |
3418 | case TextEmphasisMark::Auto: |
3419 | ASSERT_NOT_REACHED(); |
3420 | #if ASSERT_DISABLED |
3421 | FALLTHROUGH; |
3422 | #endif |
3423 | case TextEmphasisMark::Dot: |
3424 | case TextEmphasisMark::Circle: |
3425 | case TextEmphasisMark::DoubleCircle: |
3426 | case TextEmphasisMark::Triangle: |
3427 | case TextEmphasisMark::Sesame: |
3428 | auto list = CSSValueList::createSpaceSeparated(); |
3429 | list->append(cssValuePool.createValue(style.textEmphasisFill())); |
3430 | list->append(cssValuePool.createValue(style.textEmphasisMark())); |
3431 | return list; |
3432 | } |
3433 | RELEASE_ASSERT_NOT_REACHED(); |
3434 | case CSSPropertyTextIndent: { |
3435 | // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>), |
3436 | // getPropertyCSSValue() returns CSSValue. |
3437 | auto textIndent = zoomAdjustedPixelValueForLength(style.textIndent(), style); |
3438 | #if ENABLE(CSS3_TEXT) |
3439 | // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging, |
3440 | // getPropertyCSSValue() returns CSSValueList. |
3441 | if (style.textIndentLine() == TextIndentLine::EachLine || style.textIndentType() == TextIndentType::Hanging) { |
3442 | auto list = CSSValueList::createSpaceSeparated(); |
3443 | list->append(WTFMove(textIndent)); |
3444 | if (style.textIndentLine() == TextIndentLine::EachLine) |
3445 | list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine)); |
3446 | if (style.textIndentType() == TextIndentType::Hanging) |
3447 | list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging)); |
3448 | return list; |
3449 | } |
3450 | #endif |
3451 | return textIndent; |
3452 | } |
3453 | case CSSPropertyTextShadow: |
3454 | return valueForShadow(style.textShadow(), propertyID, style); |
3455 | case CSSPropertyTextRendering: |
3456 | return cssValuePool.createValue(style.fontDescription().textRenderingMode()); |
3457 | case CSSPropertyTextOverflow: |
3458 | if (style.textOverflow() == TextOverflow::Ellipsis) |
3459 | return cssValuePool.createIdentifierValue(CSSValueEllipsis); |
3460 | return cssValuePool.createIdentifierValue(CSSValueClip); |
3461 | case CSSPropertyWebkitTextSecurity: |
3462 | return cssValuePool.createValue(style.textSecurity()); |
3463 | #if ENABLE(TEXT_AUTOSIZING) |
3464 | case CSSPropertyWebkitTextSizeAdjust: |
3465 | if (style.textSizeAdjust().isAuto()) |
3466 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3467 | if (style.textSizeAdjust().isNone()) |
3468 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3469 | return CSSPrimitiveValue::create(style.textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE); |
3470 | #endif |
3471 | case CSSPropertyWebkitTextStrokeColor: |
3472 | return currentColorOrValidColor(&style, style.textStrokeColor()); |
3473 | case CSSPropertyWebkitTextStrokeWidth: |
3474 | return zoomAdjustedPixelValue(style.textStrokeWidth(), style); |
3475 | case CSSPropertyTextTransform: |
3476 | return cssValuePool.createValue(style.textTransform()); |
3477 | case CSSPropertyTop: |
3478 | return positionOffsetValue(style, CSSPropertyTop, renderer); |
3479 | case CSSPropertyUnicodeBidi: |
3480 | return cssValuePool.createValue(style.unicodeBidi()); |
3481 | case CSSPropertyVerticalAlign: |
3482 | switch (style.verticalAlign()) { |
3483 | case VerticalAlign::Baseline: |
3484 | return cssValuePool.createIdentifierValue(CSSValueBaseline); |
3485 | case VerticalAlign::Middle: |
3486 | return cssValuePool.createIdentifierValue(CSSValueMiddle); |
3487 | case VerticalAlign::Sub: |
3488 | return cssValuePool.createIdentifierValue(CSSValueSub); |
3489 | case VerticalAlign::Super: |
3490 | return cssValuePool.createIdentifierValue(CSSValueSuper); |
3491 | case VerticalAlign::TextTop: |
3492 | return cssValuePool.createIdentifierValue(CSSValueTextTop); |
3493 | case VerticalAlign::TextBottom: |
3494 | return cssValuePool.createIdentifierValue(CSSValueTextBottom); |
3495 | case VerticalAlign::Top: |
3496 | return cssValuePool.createIdentifierValue(CSSValueTop); |
3497 | case VerticalAlign::Bottom: |
3498 | return cssValuePool.createIdentifierValue(CSSValueBottom); |
3499 | case VerticalAlign::BaselineMiddle: |
3500 | return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle); |
3501 | case VerticalAlign::Length: |
3502 | return cssValuePool.createValue(style.verticalAlignLength()); |
3503 | } |
3504 | ASSERT_NOT_REACHED(); |
3505 | return nullptr; |
3506 | case CSSPropertyVisibility: |
3507 | return cssValuePool.createValue(style.visibility()); |
3508 | case CSSPropertyWhiteSpace: |
3509 | return cssValuePool.createValue(style.whiteSpace()); |
3510 | case CSSPropertyWidows: |
3511 | if (style.hasAutoWidows()) |
3512 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3513 | return cssValuePool.createValue(style.widows(), CSSPrimitiveValue::CSS_NUMBER); |
3514 | case CSSPropertyWidth: |
3515 | if (renderer && !renderer->isRenderSVGModelObject()) { |
3516 | // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property, |
3517 | // the "width" property does not apply for non-replaced inline elements. |
3518 | if (!isNonReplacedInline(*renderer)) |
3519 | return zoomAdjustedPixelValue(sizingBox(*renderer).width(), style); |
3520 | } |
3521 | return zoomAdjustedPixelValueForLength(style.width(), style); |
3522 | case CSSPropertyWillChange: |
3523 | return willChangePropertyValue(style.willChange()); |
3524 | case CSSPropertyWordBreak: |
3525 | return cssValuePool.createValue(style.wordBreak()); |
3526 | case CSSPropertyWordSpacing: |
3527 | return zoomAdjustedPixelValue(style.fontCascade().wordSpacing(), style); |
3528 | case CSSPropertyWordWrap: |
3529 | return cssValuePool.createValue(style.overflowWrap()); |
3530 | case CSSPropertyLineBreak: |
3531 | return cssValuePool.createValue(style.lineBreak()); |
3532 | case CSSPropertyWebkitNbspMode: |
3533 | return cssValuePool.createValue(style.nbspMode()); |
3534 | case CSSPropertyResize: |
3535 | return cssValuePool.createValue(style.resize()); |
3536 | case CSSPropertyWebkitFontKerning: |
3537 | return cssValuePool.createValue(style.fontDescription().kerning()); |
3538 | case CSSPropertyWebkitFontSmoothing: |
3539 | return cssValuePool.createValue(style.fontDescription().fontSmoothing()); |
3540 | case CSSPropertyFontVariantLigatures: |
3541 | return fontVariantLigaturesPropertyValue(style.fontDescription().variantCommonLigatures(), style.fontDescription().variantDiscretionaryLigatures(), style.fontDescription().variantHistoricalLigatures(), style.fontDescription().variantContextualAlternates()); |
3542 | case CSSPropertyFontVariantPosition: |
3543 | return fontVariantPositionPropertyValue(style.fontDescription().variantPosition()); |
3544 | case CSSPropertyFontVariantCaps: |
3545 | return fontVariantCapsPropertyValue(style.fontDescription().variantCaps()); |
3546 | case CSSPropertyFontVariantNumeric: |
3547 | return fontVariantNumericPropertyValue(style.fontDescription().variantNumericFigure(), style.fontDescription().variantNumericSpacing(), style.fontDescription().variantNumericFraction(), style.fontDescription().variantNumericOrdinal(), style.fontDescription().variantNumericSlashedZero()); |
3548 | case CSSPropertyFontVariantAlternates: |
3549 | return fontVariantAlternatesPropertyValue(style.fontDescription().variantAlternates()); |
3550 | case CSSPropertyFontVariantEastAsian: |
3551 | return fontVariantEastAsianPropertyValue(style.fontDescription().variantEastAsianVariant(), style.fontDescription().variantEastAsianWidth(), style.fontDescription().variantEastAsianRuby()); |
3552 | case CSSPropertyZIndex: |
3553 | if (style.hasAutoZIndex()) |
3554 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3555 | return cssValuePool.createValue(style.zIndex(), CSSPrimitiveValue::CSS_NUMBER); |
3556 | case CSSPropertyZoom: |
3557 | return cssValuePool.createValue(style.zoom(), CSSPrimitiveValue::CSS_NUMBER); |
3558 | case CSSPropertyBoxSizing: |
3559 | if (style.boxSizing() == BoxSizing::ContentBox) |
3560 | return cssValuePool.createIdentifierValue(CSSValueContentBox); |
3561 | return cssValuePool.createIdentifierValue(CSSValueBorderBox); |
3562 | case CSSPropertyAnimationDelay: |
3563 | return delayValue(style.animations()); |
3564 | case CSSPropertyAnimationDirection: { |
3565 | auto list = CSSValueList::createCommaSeparated(); |
3566 | const AnimationList* t = style.animations(); |
3567 | if (t) { |
3568 | for (size_t i = 0; i < t->size(); ++i) { |
3569 | switch (t->animation(i).direction()) { |
3570 | case Animation::AnimationDirectionNormal: |
3571 | list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
3572 | break; |
3573 | case Animation::AnimationDirectionAlternate: |
3574 | list->append(cssValuePool.createIdentifierValue(CSSValueAlternate)); |
3575 | break; |
3576 | case Animation::AnimationDirectionReverse: |
3577 | list->append(cssValuePool.createIdentifierValue(CSSValueReverse)); |
3578 | break; |
3579 | case Animation::AnimationDirectionAlternateReverse: |
3580 | list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse)); |
3581 | break; |
3582 | } |
3583 | } |
3584 | } else |
3585 | list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
3586 | return list; |
3587 | } |
3588 | case CSSPropertyAnimationDuration: |
3589 | return durationValue(style.animations()); |
3590 | case CSSPropertyAnimationFillMode: { |
3591 | auto list = CSSValueList::createCommaSeparated(); |
3592 | const AnimationList* t = style.animations(); |
3593 | if (t) { |
3594 | for (size_t i = 0; i < t->size(); ++i) { |
3595 | switch (t->animation(i).fillMode()) { |
3596 | case AnimationFillMode::None: |
3597 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3598 | break; |
3599 | case AnimationFillMode::Forwards: |
3600 | list->append(cssValuePool.createIdentifierValue(CSSValueForwards)); |
3601 | break; |
3602 | case AnimationFillMode::Backwards: |
3603 | list->append(cssValuePool.createIdentifierValue(CSSValueBackwards)); |
3604 | break; |
3605 | case AnimationFillMode::Both: |
3606 | list->append(cssValuePool.createIdentifierValue(CSSValueBoth)); |
3607 | break; |
3608 | } |
3609 | } |
3610 | } else |
3611 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3612 | return list; |
3613 | } |
3614 | case CSSPropertyAnimationIterationCount: { |
3615 | auto list = CSSValueList::createCommaSeparated(); |
3616 | const AnimationList* t = style.animations(); |
3617 | if (t) { |
3618 | for (size_t i = 0; i < t->size(); ++i) { |
3619 | double iterationCount = t->animation(i).iterationCount(); |
3620 | if (iterationCount == Animation::IterationCountInfinite) |
3621 | list->append(cssValuePool.createIdentifierValue(CSSValueInfinite)); |
3622 | else |
3623 | list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); |
3624 | } |
3625 | } else |
3626 | list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); |
3627 | return list; |
3628 | } |
3629 | case CSSPropertyAnimationName: { |
3630 | auto list = CSSValueList::createCommaSeparated(); |
3631 | const AnimationList* t = style.animations(); |
3632 | if (t) { |
3633 | for (size_t i = 0; i < t->size(); ++i) |
3634 | list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING)); |
3635 | } else |
3636 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3637 | return list; |
3638 | } |
3639 | case CSSPropertyAnimationPlayState: { |
3640 | auto list = CSSValueList::createCommaSeparated(); |
3641 | const AnimationList* t = style.animations(); |
3642 | if (t) { |
3643 | for (size_t i = 0; i < t->size(); ++i) { |
3644 | switch (t->animation(i).playState()) { |
3645 | case AnimationPlayState::Playing: |
3646 | list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); |
3647 | break; |
3648 | case AnimationPlayState::Paused: |
3649 | list->append(cssValuePool.createIdentifierValue(CSSValuePaused)); |
3650 | break; |
3651 | } |
3652 | } |
3653 | } else |
3654 | list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); |
3655 | return list; |
3656 | } |
3657 | case CSSPropertyAnimationTimingFunction: |
3658 | return timingFunctionValue(style.animations()); |
3659 | case CSSPropertyWebkitAppearance: |
3660 | return cssValuePool.createValue(style.appearance()); |
3661 | case CSSPropertyWebkitAspectRatio: |
3662 | switch (style.aspectRatioType()) { |
3663 | case AspectRatioType::Auto: |
3664 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3665 | case AspectRatioType::FromDimensions: |
3666 | return cssValuePool.createIdentifierValue(CSSValueFromDimensions); |
3667 | case AspectRatioType::FromIntrinsic: |
3668 | return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic); |
3669 | case AspectRatioType::Specified: |
3670 | return CSSAspectRatioValue::create(style.aspectRatioNumerator(), style.aspectRatioDenominator()); |
3671 | } |
3672 | ASSERT_NOT_REACHED(); |
3673 | return nullptr; |
3674 | case CSSPropertyWebkitBackfaceVisibility: |
3675 | return cssValuePool.createIdentifierValue((style.backfaceVisibility() == BackfaceVisibility::Hidden) ? CSSValueHidden : CSSValueVisible); |
3676 | case CSSPropertyWebkitBorderImage: |
3677 | return valueForNinePieceImage(style.borderImage()); |
3678 | case CSSPropertyBorderImageOutset: |
3679 | return valueForNinePieceImageQuad(style.borderImage().outset()); |
3680 | case CSSPropertyBorderImageRepeat: |
3681 | return valueForNinePieceImageRepeat(style.borderImage()); |
3682 | case CSSPropertyBorderImageSlice: |
3683 | return valueForNinePieceImageSlice(style.borderImage()); |
3684 | case CSSPropertyBorderImageWidth: |
3685 | return valueForNinePieceImageQuad(style.borderImage().borderSlices()); |
3686 | case CSSPropertyWebkitMaskBoxImage: |
3687 | return valueForNinePieceImage(style.maskBoxImage()); |
3688 | case CSSPropertyWebkitMaskBoxImageOutset: |
3689 | return valueForNinePieceImageQuad(style.maskBoxImage().outset()); |
3690 | case CSSPropertyWebkitMaskBoxImageRepeat: |
3691 | return valueForNinePieceImageRepeat(style.maskBoxImage()); |
3692 | case CSSPropertyWebkitMaskBoxImageSlice: |
3693 | return valueForNinePieceImageSlice(style.maskBoxImage()); |
3694 | case CSSPropertyWebkitMaskBoxImageWidth: |
3695 | return valueForNinePieceImageQuad(style.maskBoxImage().borderSlices()); |
3696 | case CSSPropertyWebkitMaskBoxImageSource: |
3697 | if (style.maskBoxImageSource()) |
3698 | return style.maskBoxImageSource()->cssValue(); |
3699 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3700 | case CSSPropertyWebkitFontSizeDelta: |
3701 | // Not a real style property -- used by the editing engine -- so has no computed value. |
3702 | break; |
3703 | case CSSPropertyWebkitInitialLetter: { |
3704 | auto drop = !style.initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER); |
3705 | auto size = !style.initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER); |
3706 | return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size))); |
3707 | } |
3708 | case CSSPropertyWebkitMarginBottomCollapse: |
3709 | case CSSPropertyWebkitMarginAfterCollapse: |
3710 | return cssValuePool.createValue(style.marginAfterCollapse()); |
3711 | case CSSPropertyWebkitMarginTopCollapse: |
3712 | case CSSPropertyWebkitMarginBeforeCollapse: |
3713 | return cssValuePool.createValue(style.marginBeforeCollapse()); |
3714 | #if ENABLE(OVERFLOW_SCROLLING_TOUCH) |
3715 | case CSSPropertyWebkitOverflowScrolling: |
3716 | if (!style.useTouchOverflowScrolling()) |
3717 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3718 | return cssValuePool.createIdentifierValue(CSSValueTouch); |
3719 | #endif |
3720 | case CSSPropertyPerspective: |
3721 | if (!style.hasPerspective()) |
3722 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3723 | return zoomAdjustedPixelValue(style.perspective(), style); |
3724 | case CSSPropertyPerspectiveOrigin: { |
3725 | auto list = CSSValueList::createSpaceSeparated(); |
3726 | if (renderer) { |
3727 | LayoutRect box; |
3728 | if (is<RenderBox>(*renderer)) |
3729 | box = downcast<RenderBox>(*renderer).borderBoxRect(); |
3730 | |
3731 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginX(), box.width()), style)); |
3732 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginY(), box.height()), style)); |
3733 | } else { |
3734 | list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginX(), style)); |
3735 | list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginY(), style)); |
3736 | } |
3737 | return list; |
3738 | } |
3739 | case CSSPropertyWebkitRtlOrdering: |
3740 | return cssValuePool.createIdentifierValue(style.rtlOrdering() == Order::Visual ? CSSValueVisual : CSSValueLogical); |
3741 | #if ENABLE(TOUCH_EVENTS) |
3742 | case CSSPropertyWebkitTapHighlightColor: |
3743 | return currentColorOrValidColor(&style, style.tapHighlightColor()); |
3744 | #endif |
3745 | #if ENABLE(POINTER_EVENTS) |
3746 | case CSSPropertyTouchAction: |
3747 | return touchActionFlagsToCSSValue(style.touchActions()); |
3748 | #endif |
3749 | #if PLATFORM(IOS_FAMILY) |
3750 | case CSSPropertyWebkitTouchCallout: |
3751 | return cssValuePool.createIdentifierValue(style.touchCalloutEnabled() ? CSSValueDefault : CSSValueNone); |
3752 | #endif |
3753 | case CSSPropertyWebkitUserDrag: |
3754 | return cssValuePool.createValue(style.userDrag()); |
3755 | case CSSPropertyWebkitUserSelect: |
3756 | return cssValuePool.createValue(style.userSelect()); |
3757 | case CSSPropertyBorderBottomLeftRadius: |
3758 | return borderRadiusCornerValue(style.borderBottomLeftRadius(), style); |
3759 | case CSSPropertyBorderBottomRightRadius: |
3760 | return borderRadiusCornerValue(style.borderBottomRightRadius(), style); |
3761 | case CSSPropertyBorderTopLeftRadius: |
3762 | return borderRadiusCornerValue(style.borderTopLeftRadius(), style); |
3763 | case CSSPropertyBorderTopRightRadius: |
3764 | return borderRadiusCornerValue(style.borderTopRightRadius(), style); |
3765 | case CSSPropertyClip: { |
3766 | if (!style.hasClip()) |
3767 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3768 | auto rect = Rect::create(); |
3769 | rect->setTop(autoOrZoomAdjustedValue(style.clip().top(), style)); |
3770 | rect->setRight(autoOrZoomAdjustedValue(style.clip().right(), style)); |
3771 | rect->setBottom(autoOrZoomAdjustedValue(style.clip().bottom(), style)); |
3772 | rect->setLeft(autoOrZoomAdjustedValue(style.clip().left(), style)); |
3773 | return cssValuePool.createValue(WTFMove(rect)); |
3774 | } |
3775 | case CSSPropertySpeakAs: |
3776 | return speakAsToCSSValue(style.speakAs()); |
3777 | case CSSPropertyTransform: |
3778 | return computedTransform(renderer, style); |
3779 | case CSSPropertyTransformBox: |
3780 | return CSSPrimitiveValue::create(style.transformBox()); |
3781 | case CSSPropertyTransformOrigin: { |
3782 | auto list = CSSValueList::createSpaceSeparated(); |
3783 | if (renderer) { |
3784 | LayoutRect box; |
3785 | if (is<RenderBox>(*renderer)) |
3786 | box = downcast<RenderBox>(*renderer).borderBoxRect(); |
3787 | |
3788 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginX(), box.width()), style)); |
3789 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginY(), box.height()), style)); |
3790 | if (style.transformOriginZ()) |
3791 | list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style)); |
3792 | } else { |
3793 | list->append(zoomAdjustedPixelValueForLength(style.transformOriginX(), style)); |
3794 | list->append(zoomAdjustedPixelValueForLength(style.transformOriginY(), style)); |
3795 | if (style.transformOriginZ()) |
3796 | list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style)); |
3797 | } |
3798 | return list; |
3799 | } |
3800 | case CSSPropertyTransformStyle: |
3801 | case CSSPropertyWebkitTransformStyle: |
3802 | return cssValuePool.createIdentifierValue((style.transformStyle3D() == TransformStyle3D::Preserve3D) ? CSSValuePreserve3d : CSSValueFlat); |
3803 | case CSSPropertyTransitionDelay: |
3804 | return delayValue(style.transitions()); |
3805 | case CSSPropertyTransitionDuration: |
3806 | return durationValue(style.transitions()); |
3807 | case CSSPropertyTransitionProperty: |
3808 | return transitionPropertyValue(style.transitions()); |
3809 | case CSSPropertyTransitionTimingFunction: |
3810 | return timingFunctionValue(style.transitions()); |
3811 | case CSSPropertyTransition: { |
3812 | if (auto* animationList = style.transitions()) { |
3813 | auto transitionsList = CSSValueList::createCommaSeparated(); |
3814 | for (size_t i = 0; i < animationList->size(); ++i) { |
3815 | auto list = CSSValueList::createSpaceSeparated(); |
3816 | auto& animation = animationList->animation(i); |
3817 | list->append(createTransitionPropertyValue(animation)); |
3818 | list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S)); |
3819 | list->append(createTimingFunctionValue(*animation.timingFunction())); |
3820 | list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S)); |
3821 | transitionsList->append(WTFMove(list)); |
3822 | } |
3823 | return transitionsList; |
3824 | } |
3825 | |
3826 | auto list = CSSValueList::createSpaceSeparated(); |
3827 | // transition-property default value. |
3828 | list->append(cssValuePool.createIdentifierValue(CSSValueAll)); |
3829 | list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S)); |
3830 | list->append(createTimingFunctionValue(Animation::initialTimingFunction())); |
3831 | list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S)); |
3832 | return list; |
3833 | } |
3834 | case CSSPropertyPointerEvents: |
3835 | return cssValuePool.createValue(style.pointerEvents()); |
3836 | case CSSPropertyWebkitLineGrid: |
3837 | if (style.lineGrid().isNull()) |
3838 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3839 | return cssValuePool.createValue(style.lineGrid(), CSSPrimitiveValue::CSS_STRING); |
3840 | case CSSPropertyWebkitLineSnap: |
3841 | return CSSPrimitiveValue::create(style.lineSnap()); |
3842 | case CSSPropertyWebkitLineAlign: |
3843 | return CSSPrimitiveValue::create(style.lineAlign()); |
3844 | case CSSPropertyWritingMode: |
3845 | return cssValuePool.createValue(style.writingMode()); |
3846 | case CSSPropertyWebkitTextCombine: |
3847 | return cssValuePool.createValue(style.textCombine()); |
3848 | case CSSPropertyWebkitTextOrientation: |
3849 | return CSSPrimitiveValue::create(style.textOrientation()); |
3850 | case CSSPropertyWebkitLineBoxContain: |
3851 | return createLineBoxContainValue(style.lineBoxContain()); |
3852 | case CSSPropertyAlt: |
3853 | return altTextToCSSValue(style); |
3854 | case CSSPropertyContent: |
3855 | return contentToCSSValue(style); |
3856 | case CSSPropertyCounterIncrement: |
3857 | return counterToCSSValue(style, propertyID); |
3858 | case CSSPropertyCounterReset: |
3859 | return counterToCSSValue(style, propertyID); |
3860 | case CSSPropertyWebkitClipPath: { |
3861 | auto* operation = style.clipPath(); |
3862 | if (!operation) |
3863 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3864 | if (is<ReferenceClipPathOperation>(*operation)) |
3865 | return CSSPrimitiveValue::create(downcast<ReferenceClipPathOperation>(*operation).url(), CSSPrimitiveValue::CSS_URI); |
3866 | auto list = CSSValueList::createSpaceSeparated(); |
3867 | if (is<ShapeClipPathOperation>(*operation)) { |
3868 | auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation); |
3869 | list->append(valueForBasicShape(style, shapeOperation.basicShape())); |
3870 | if (shapeOperation.referenceBox() != CSSBoxType::BoxMissing) |
3871 | list->append(cssValuePool.createValue(shapeOperation.referenceBox())); |
3872 | } |
3873 | if (is<BoxClipPathOperation>(*operation)) |
3874 | list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox())); |
3875 | return list; |
3876 | } |
3877 | case CSSPropertyShapeMargin: |
3878 | return cssValuePool.createValue(style.shapeMargin(), style); |
3879 | case CSSPropertyShapeImageThreshold: |
3880 | return cssValuePool.createValue(style.shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER); |
3881 | case CSSPropertyShapeOutside: |
3882 | return shapePropertyValue(style, style.shapeOutside()); |
3883 | case CSSPropertyFilter: |
3884 | return valueForFilter(style, style.filter()); |
3885 | case CSSPropertyAppleColorFilter: |
3886 | return valueForFilter(style, style.appleColorFilter()); |
3887 | #if ENABLE(FILTERS_LEVEL_2) |
3888 | case CSSPropertyWebkitBackdropFilter: |
3889 | return valueForFilter(style, style.backdropFilter()); |
3890 | #endif |
3891 | #if ENABLE(CSS_COMPOSITING) |
3892 | case CSSPropertyMixBlendMode: |
3893 | return cssValuePool.createValue(style.blendMode()); |
3894 | case CSSPropertyIsolation: |
3895 | return cssValuePool.createValue(style.isolation()); |
3896 | #endif |
3897 | case CSSPropertyBackgroundBlendMode: { |
3898 | auto& layers = style.backgroundLayers(); |
3899 | if (!layers.next()) |
3900 | return cssValuePool.createValue(layers.blendMode()); |
3901 | auto list = CSSValueList::createCommaSeparated(); |
3902 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
3903 | list->append(cssValuePool.createValue(currLayer->blendMode())); |
3904 | return list; |
3905 | } |
3906 | case CSSPropertyBackground: |
3907 | return getBackgroundShorthandValue(); |
3908 | case CSSPropertyBorder: { |
3909 | auto value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout); |
3910 | const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; |
3911 | for (auto& property : properties) { |
3912 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout))) |
3913 | return nullptr; |
3914 | } |
3915 | return value; |
3916 | } |
3917 | case CSSPropertyBorderBlock: { |
3918 | auto value = propertyValue(CSSPropertyBorderBlockStart, DoNotUpdateLayout); |
3919 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderBlockEnd, DoNotUpdateLayout))) |
3920 | return nullptr; |
3921 | return value; |
3922 | } |
3923 | case CSSPropertyBorderBlockColor: |
3924 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockColorShorthand()); |
3925 | case CSSPropertyBorderBlockStyle: |
3926 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockStyleShorthand()); |
3927 | case CSSPropertyBorderBlockWidth: |
3928 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockWidthShorthand()); |
3929 | case CSSPropertyBorderBottom: |
3930 | return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand()); |
3931 | case CSSPropertyBorderColor: |
3932 | return getCSSPropertyValuesFor4SidesShorthand(borderColorShorthand()); |
3933 | case CSSPropertyBorderLeft: |
3934 | return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand()); |
3935 | case CSSPropertyBorderImage: |
3936 | return valueForNinePieceImage(style.borderImage()); |
3937 | case CSSPropertyBorderInline: { |
3938 | auto value = propertyValue(CSSPropertyBorderInlineStart, DoNotUpdateLayout); |
3939 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderInlineEnd, DoNotUpdateLayout))) |
3940 | return nullptr; |
3941 | return value; |
3942 | } |
3943 | case CSSPropertyBorderInlineColor: |
3944 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineColorShorthand()); |
3945 | case CSSPropertyBorderInlineStyle: |
3946 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineStyleShorthand()); |
3947 | case CSSPropertyBorderInlineWidth: |
3948 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineWidthShorthand()); |
3949 | case CSSPropertyBorderRadius: |
3950 | return borderRadiusShorthandValue(style); |
3951 | case CSSPropertyBorderRight: |
3952 | return getCSSPropertyValuesForShorthandProperties(borderRightShorthand()); |
3953 | case CSSPropertyBorderStyle: |
3954 | return getCSSPropertyValuesFor4SidesShorthand(borderStyleShorthand()); |
3955 | case CSSPropertyBorderTop: |
3956 | return getCSSPropertyValuesForShorthandProperties(borderTopShorthand()); |
3957 | case CSSPropertyBorderWidth: |
3958 | return getCSSPropertyValuesFor4SidesShorthand(borderWidthShorthand()); |
3959 | case CSSPropertyColumnRule: |
3960 | return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand()); |
3961 | case CSSPropertyColumns: |
3962 | return getCSSPropertyValuesForShorthandProperties(columnsShorthand()); |
3963 | case CSSPropertyInset: |
3964 | return getCSSPropertyValuesFor4SidesShorthand(insetShorthand()); |
3965 | case CSSPropertyInsetBlock: |
3966 | return getCSSPropertyValuesFor2SidesShorthand(insetBlockShorthand()); |
3967 | case CSSPropertyInsetInline: |
3968 | return getCSSPropertyValuesFor2SidesShorthand(insetInlineShorthand()); |
3969 | case CSSPropertyListStyle: |
3970 | return getCSSPropertyValuesForShorthandProperties(listStyleShorthand()); |
3971 | case CSSPropertyMargin: |
3972 | return getCSSPropertyValuesFor4SidesShorthand(marginShorthand()); |
3973 | case CSSPropertyMarginBlock: |
3974 | return getCSSPropertyValuesFor2SidesShorthand(marginBlockShorthand()); |
3975 | case CSSPropertyMarginInline: |
3976 | return getCSSPropertyValuesFor2SidesShorthand(marginInlineShorthand()); |
3977 | case CSSPropertyOutline: |
3978 | return getCSSPropertyValuesForShorthandProperties(outlineShorthand()); |
3979 | case CSSPropertyPadding: |
3980 | return getCSSPropertyValuesFor4SidesShorthand(paddingShorthand()); |
3981 | case CSSPropertyPaddingBlock: |
3982 | return getCSSPropertyValuesFor2SidesShorthand(paddingBlockShorthand()); |
3983 | case CSSPropertyPaddingInline: |
3984 | return getCSSPropertyValuesFor2SidesShorthand(paddingInlineShorthand()); |
3985 | #if ENABLE(CSS_SCROLL_SNAP) |
3986 | case CSSPropertyScrollSnapMargin: |
3987 | return getCSSPropertyValuesFor4SidesShorthand(scrollSnapMarginShorthand()); |
3988 | case CSSPropertyScrollSnapMarginBottom: |
3989 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginBottom(), style); |
3990 | case CSSPropertyScrollSnapMarginTop: |
3991 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginTop(), style); |
3992 | case CSSPropertyScrollSnapMarginRight: |
3993 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginRight(), style); |
3994 | case CSSPropertyScrollSnapMarginLeft: |
3995 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginLeft(), style); |
3996 | case CSSPropertyScrollPadding: |
3997 | return getCSSPropertyValuesFor4SidesShorthand(scrollPaddingShorthand()); |
3998 | case CSSPropertyScrollPaddingBottom: |
3999 | return zoomAdjustedPixelValueForLength(style.scrollPaddingBottom(), style); |
4000 | case CSSPropertyScrollPaddingTop: |
4001 | return zoomAdjustedPixelValueForLength(style.scrollPaddingTop(), style); |
4002 | case CSSPropertyScrollPaddingRight: |
4003 | return zoomAdjustedPixelValueForLength(style.scrollPaddingRight(), style); |
4004 | case CSSPropertyScrollPaddingLeft: |
4005 | return zoomAdjustedPixelValueForLength(style.scrollPaddingLeft(), style); |
4006 | case CSSPropertyScrollSnapType: |
4007 | return valueForScrollSnapType(style.scrollSnapType()); |
4008 | case CSSPropertyScrollSnapAlign: |
4009 | return valueForScrollSnapAlignment(style.scrollSnapAlign()); |
4010 | #endif |
4011 | |
4012 | #if ENABLE(CSS_TRAILING_WORD) |
4013 | case CSSPropertyAppleTrailingWord: |
4014 | return cssValuePool.createValue(style.trailingWord()); |
4015 | #endif |
4016 | |
4017 | #if ENABLE(APPLE_PAY) |
4018 | case CSSPropertyApplePayButtonStyle: |
4019 | return cssValuePool.createValue(style.applePayButtonStyle()); |
4020 | case CSSPropertyApplePayButtonType: |
4021 | return cssValuePool.createValue(style.applePayButtonType()); |
4022 | #endif |
4023 | |
4024 | #if ENABLE(DARK_MODE_CSS) |
4025 | case CSSPropertyColorScheme: { |
4026 | if (!RuntimeEnabledFeatures::sharedFeatures().darkModeCSSEnabled()) |
4027 | return nullptr; |
4028 | |
4029 | auto colorScheme = style.colorScheme(); |
4030 | if (colorScheme.isAuto()) |
4031 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
4032 | |
4033 | auto list = CSSValueList::createSpaceSeparated(); |
4034 | if (colorScheme.contains(ColorScheme::Light)) |
4035 | list->append(cssValuePool.createIdentifierValue(CSSValueLight)); |
4036 | if (colorScheme.contains(ColorScheme::Dark)) |
4037 | list->append(cssValuePool.createIdentifierValue(CSSValueDark)); |
4038 | if (!colorScheme.allowsTransformations()) |
4039 | list->append(cssValuePool.createIdentifierValue(CSSValueOnly)); |
4040 | ASSERT(list->length()); |
4041 | return list; |
4042 | } |
4043 | #endif |
4044 | |
4045 | /* Individual properties not part of the spec */ |
4046 | case CSSPropertyBackgroundRepeatX: |
4047 | case CSSPropertyBackgroundRepeatY: |
4048 | break; |
4049 | |
4050 | // Length properties for SVG. |
4051 | case CSSPropertyCx: |
4052 | return zoomAdjustedPixelValueForLength(style.svgStyle().cx(), style); |
4053 | case CSSPropertyCy: |
4054 | return zoomAdjustedPixelValueForLength(style.svgStyle().cy(), style); |
4055 | case CSSPropertyR: |
4056 | return zoomAdjustedPixelValueForLength(style.svgStyle().r(), style); |
4057 | case CSSPropertyRx: |
4058 | return zoomAdjustedPixelValueForLength(style.svgStyle().rx(), style); |
4059 | case CSSPropertyRy: |
4060 | return zoomAdjustedPixelValueForLength(style.svgStyle().ry(), style); |
4061 | case CSSPropertyStrokeDashoffset: |
4062 | return zoomAdjustedPixelValueForLength(style.svgStyle().strokeDashOffset(), style); |
4063 | case CSSPropertyX: |
4064 | return zoomAdjustedPixelValueForLength(style.svgStyle().x(), style); |
4065 | case CSSPropertyY: |
4066 | return zoomAdjustedPixelValueForLength(style.svgStyle().y(), style); |
4067 | case CSSPropertyWebkitTextZoom: |
4068 | return cssValuePool.createValue(style.textZoom()); |
4069 | |
4070 | case CSSPropertyPaintOrder: |
4071 | return paintOrder(style.paintOrder()); |
4072 | case CSSPropertyStrokeLinecap: |
4073 | return CSSPrimitiveValue::create(style.capStyle()); |
4074 | case CSSPropertyStrokeLinejoin: |
4075 | return CSSPrimitiveValue::create(style.joinStyle()); |
4076 | case CSSPropertyStrokeWidth: |
4077 | return zoomAdjustedPixelValueForLength(style.strokeWidth(), style); |
4078 | case CSSPropertyStrokeColor: |
4079 | return currentColorOrValidColor(&style, style.strokeColor()); |
4080 | case CSSPropertyStrokeMiterlimit: |
4081 | return CSSPrimitiveValue::create(style.strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER); |
4082 | |
4083 | /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */ |
4084 | case CSSPropertyAll: |
4085 | case CSSPropertyAnimation: |
4086 | case CSSPropertyWebkitTextEmphasis: |
4087 | break; |
4088 | |
4089 | /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */ |
4090 | case CSSPropertyBorderBlockEnd: |
4091 | case CSSPropertyBorderBlockEndColor: |
4092 | case CSSPropertyBorderBlockEndStyle: |
4093 | case CSSPropertyBorderBlockEndWidth: |
4094 | case CSSPropertyBorderBlockStart: |
4095 | case CSSPropertyBorderBlockStartColor: |
4096 | case CSSPropertyBorderBlockStartStyle: |
4097 | case CSSPropertyBorderBlockStartWidth: |
4098 | case CSSPropertyBorderInlineEnd: |
4099 | case CSSPropertyBorderInlineEndColor: |
4100 | case CSSPropertyBorderInlineEndStyle: |
4101 | case CSSPropertyBorderInlineEndWidth: |
4102 | case CSSPropertyBorderInlineStart: |
4103 | case CSSPropertyBorderInlineStartColor: |
4104 | case CSSPropertyBorderInlineStartStyle: |
4105 | case CSSPropertyBorderInlineStartWidth: |
4106 | case CSSPropertyInsetBlockEnd: |
4107 | case CSSPropertyInsetBlockStart: |
4108 | case CSSPropertyInsetInlineEnd: |
4109 | case CSSPropertyInsetInlineStart: |
4110 | case CSSPropertyMarginBlockEnd: |
4111 | case CSSPropertyMarginBlockStart: |
4112 | case CSSPropertyMarginInlineEnd: |
4113 | case CSSPropertyMarginInlineStart: |
4114 | case CSSPropertyPaddingBlockEnd: |
4115 | case CSSPropertyPaddingBlockStart: |
4116 | case CSSPropertyPaddingInlineEnd: |
4117 | case CSSPropertyPaddingInlineStart: |
4118 | case CSSPropertyBlockSize: |
4119 | case CSSPropertyInlineSize: |
4120 | case CSSPropertyMaxBlockSize: |
4121 | case CSSPropertyMaxInlineSize: |
4122 | case CSSPropertyMinBlockSize: |
4123 | case CSSPropertyMinInlineSize: |
4124 | ASSERT_NOT_REACHED(); |
4125 | break; |
4126 | |
4127 | /* Unimplemented @font-face properties */ |
4128 | case CSSPropertySrc: |
4129 | case CSSPropertyUnicodeRange: |
4130 | case CSSPropertyFontDisplay: |
4131 | break; |
4132 | |
4133 | /* Other unimplemented properties */ |
4134 | case CSSPropertyPage: // for @page |
4135 | case CSSPropertyQuotes: // FIXME: needs implementation |
4136 | case CSSPropertySize: // for @page |
4137 | break; |
4138 | |
4139 | /* Unimplemented -webkit- properties */ |
4140 | case CSSPropertyWebkitBorderRadius: |
4141 | case CSSPropertyWebkitMarginCollapse: |
4142 | case CSSPropertyWebkitMarquee: |
4143 | case CSSPropertyWebkitMarqueeSpeed: |
4144 | case CSSPropertyWebkitMask: |
4145 | case CSSPropertyWebkitMaskRepeatX: |
4146 | case CSSPropertyWebkitMaskRepeatY: |
4147 | case CSSPropertyPerspectiveOriginX: |
4148 | case CSSPropertyPerspectiveOriginY: |
4149 | case CSSPropertyWebkitTextStroke: |
4150 | case CSSPropertyTransformOriginX: |
4151 | case CSSPropertyTransformOriginY: |
4152 | case CSSPropertyTransformOriginZ: |
4153 | break; |
4154 | |
4155 | #if ENABLE(CSS_DEVICE_ADAPTATION) |
4156 | case CSSPropertyMaxZoom: |
4157 | case CSSPropertyMinZoom: |
4158 | case CSSPropertyOrientation: |
4159 | case CSSPropertyUserZoom: |
4160 | break; |
4161 | #endif |
4162 | |
4163 | case CSSPropertyBufferedRendering: |
4164 | case CSSPropertyClipPath: |
4165 | case CSSPropertyClipRule: |
4166 | case CSSPropertyMask: |
4167 | case CSSPropertyEnableBackground: |
4168 | case CSSPropertyFloodColor: |
4169 | case CSSPropertyFloodOpacity: |
4170 | case CSSPropertyLightingColor: |
4171 | case CSSPropertyStopColor: |
4172 | case CSSPropertyStopOpacity: |
4173 | case CSSPropertyColorInterpolation: |
4174 | case CSSPropertyColorInterpolationFilters: |
4175 | case CSSPropertyColorProfile: |
4176 | case CSSPropertyColorRendering: |
4177 | case CSSPropertyFill: |
4178 | case CSSPropertyFillOpacity: |
4179 | case CSSPropertyFillRule: |
4180 | case CSSPropertyMarker: |
4181 | case CSSPropertyMarkerEnd: |
4182 | case CSSPropertyMarkerMid: |
4183 | case CSSPropertyMarkerStart: |
4184 | case CSSPropertyMaskType: |
4185 | case CSSPropertyShapeRendering: |
4186 | case CSSPropertyStroke: |
4187 | case CSSPropertyStrokeDasharray: |
4188 | case CSSPropertyStrokeOpacity: |
4189 | case CSSPropertyAlignmentBaseline: |
4190 | case CSSPropertyBaselineShift: |
4191 | case CSSPropertyDominantBaseline: |
4192 | case CSSPropertyGlyphOrientationHorizontal: |
4193 | case CSSPropertyGlyphOrientationVertical: |
4194 | case CSSPropertyKerning: |
4195 | case CSSPropertyTextAnchor: |
4196 | case CSSPropertyVectorEffect: |
4197 | return svgPropertyValue(propertyID); |
4198 | case CSSPropertyCustom: |
4199 | ASSERT_NOT_REACHED(); |
4200 | return nullptr; |
4201 | } |
4202 | |
4203 | logUnimplementedPropertyID(propertyID); |
4204 | return nullptr; |
4205 | } |
4206 | |
4207 | String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const |
4208 | { |
4209 | auto value = getPropertyCSSValue(propertyID); |
4210 | if (!value) |
4211 | return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue? |
4212 | return value->cssText(); |
4213 | } |
4214 | |
4215 | unsigned CSSComputedStyleDeclaration::length() const |
4216 | { |
4217 | updateStyleIfNeededForProperty(m_element.get(), CSSPropertyCustom); |
4218 | |
4219 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
4220 | if (!style) |
4221 | return 0; |
4222 | |
4223 | return numComputedProperties + style->inheritedCustomProperties().size() + style->nonInheritedCustomProperties().size(); |
4224 | } |
4225 | |
4226 | String CSSComputedStyleDeclaration::item(unsigned i) const |
4227 | { |
4228 | if (i >= length()) |
4229 | return String(); |
4230 | |
4231 | if (i < numComputedProperties) |
4232 | return getPropertyNameString(computedProperties[i]); |
4233 | |
4234 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
4235 | if (!style) |
4236 | return String(); |
4237 | |
4238 | const auto& inheritedCustomProperties = style->inheritedCustomProperties(); |
4239 | |
4240 | if (i < numComputedProperties + inheritedCustomProperties.size()) { |
4241 | auto results = copyToVector(inheritedCustomProperties.keys()); |
4242 | return results.at(i - numComputedProperties); |
4243 | } |
4244 | |
4245 | const auto& nonInheritedCustomProperties = style->nonInheritedCustomProperties(); |
4246 | auto results = copyToVector(nonInheritedCustomProperties.keys()); |
4247 | return results.at(i - inheritedCustomProperties.size() - numComputedProperties); |
4248 | } |
4249 | |
4250 | bool ComputedStyleExtractor::(CSSPropertyID propertyID, const CSSValue* value) |
4251 | { |
4252 | if (!m_element) |
4253 | return false; |
4254 | if (propertyID == CSSPropertyFontSize && is<CSSPrimitiveValue>(*value)) { |
4255 | m_element->document().updateLayoutIgnorePendingStylesheets(); |
4256 | if (auto* style = m_element->computedStyle(m_pseudoElementSpecifier)) { |
4257 | if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) { |
4258 | auto& primitiveValue = downcast<CSSPrimitiveValue>(*value); |
4259 | if (primitiveValue.isValueID() && primitiveValue.valueID() == sizeIdentifier) |
4260 | return true; |
4261 | } |
4262 | } |
4263 | } |
4264 | RefPtr<CSSValue> computedValue = propertyValue(propertyID); |
4265 | return computedValue && value && computedValue->equals(*value); |
4266 | } |
4267 | |
4268 | Ref<MutableStyleProperties> ComputedStyleExtractor::() |
4269 | { |
4270 | return copyPropertiesInSet(computedProperties, numComputedProperties); |
4271 | } |
4272 | |
4273 | Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) |
4274 | { |
4275 | auto list = CSSValueList::createSpaceSeparated(); |
4276 | for (size_t i = 0; i < shorthand.length(); ++i) |
4277 | list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); |
4278 | return list; |
4279 | } |
4280 | |
4281 | RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor2SidesShorthand(const StylePropertyShorthand& shorthand) |
4282 | { |
4283 | auto list = CSSValueList::createSpaceSeparated(); |
4284 | |
4285 | // Assume the properties are in the usual order start, end. |
4286 | auto startValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); |
4287 | auto endValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); |
4288 | |
4289 | // All 2 properties must be specified. |
4290 | if (!startValue || !endValue) |
4291 | return nullptr; |
4292 | |
4293 | bool showEnd = !compareCSSValuePtr(startValue, endValue); |
4294 | |
4295 | list->append(startValue.releaseNonNull()); |
4296 | if (showEnd) |
4297 | list->append(endValue.releaseNonNull()); |
4298 | |
4299 | return list; |
4300 | } |
4301 | |
4302 | RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor4SidesShorthand(const StylePropertyShorthand& shorthand) |
4303 | { |
4304 | auto list = CSSValueList::createSpaceSeparated(); |
4305 | |
4306 | // Assume the properties are in the usual order top, right, bottom, left. |
4307 | auto topValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); |
4308 | auto rightValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); |
4309 | auto bottomValue = propertyValue(shorthand.properties()[2], DoNotUpdateLayout); |
4310 | auto leftValue = propertyValue(shorthand.properties()[3], DoNotUpdateLayout); |
4311 | |
4312 | // All 4 properties must be specified. |
4313 | if (!topValue || !rightValue || !bottomValue || !leftValue) |
4314 | return nullptr; |
4315 | |
4316 | bool showLeft = !compareCSSValuePtr(rightValue, leftValue); |
4317 | bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft; |
4318 | bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom; |
4319 | |
4320 | list->append(topValue.releaseNonNull()); |
4321 | if (showRight) |
4322 | list->append(rightValue.releaseNonNull()); |
4323 | if (showBottom) |
4324 | list->append(bottomValue.releaseNonNull()); |
4325 | if (showLeft) |
4326 | list->append(leftValue.releaseNonNull()); |
4327 | |
4328 | return list; |
4329 | } |
4330 | |
4331 | Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) |
4332 | { |
4333 | auto list = CSSValueList::createSlashSeparated(); |
4334 | for (size_t i = 0; i < shorthand.length(); ++i) |
4335 | list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); |
4336 | return list; |
4337 | } |
4338 | |
4339 | Ref<MutableStyleProperties> ComputedStyleExtractor::(const CSSPropertyID* set, unsigned length) |
4340 | { |
4341 | Vector<CSSProperty, 256> list; |
4342 | list.reserveInitialCapacity(length); |
4343 | for (unsigned i = 0; i < length; ++i) { |
4344 | if (auto value = propertyValue(set[i])) |
4345 | list.append(CSSProperty(set[i], WTFMove(value), false)); |
4346 | } |
4347 | return MutableStyleProperties::create(list.data(), list.size()); |
4348 | } |
4349 | |
4350 | CSSRule* CSSComputedStyleDeclaration::parentRule() const |
4351 | { |
4352 | return nullptr; |
4353 | } |
4354 | |
4355 | RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) |
4356 | { |
4357 | if (isCustomPropertyName(propertyName)) { |
4358 | auto value = ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName); |
4359 | if (!value) |
4360 | return nullptr; |
4361 | return value->createDeprecatedCSSOMWrapper(*this); |
4362 | } |
4363 | |
4364 | CSSPropertyID propertyID = cssPropertyID(propertyName); |
4365 | if (!propertyID) |
4366 | return nullptr; |
4367 | auto value = getPropertyCSSValue(propertyID); |
4368 | if (!value) |
4369 | return nullptr; |
4370 | return value->createDeprecatedCSSOMWrapper(*this); |
4371 | } |
4372 | |
4373 | String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName) |
4374 | { |
4375 | if (isCustomPropertyName(propertyName)) |
4376 | return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName); |
4377 | |
4378 | CSSPropertyID propertyID = cssPropertyID(propertyName); |
4379 | if (!propertyID) |
4380 | return String(); |
4381 | return getPropertyValue(propertyID); |
4382 | } |
4383 | |
4384 | String CSSComputedStyleDeclaration::getPropertyPriority(const String&) |
4385 | { |
4386 | // All computed styles have a priority of not "important". |
4387 | return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? |
4388 | } |
4389 | |
4390 | String CSSComputedStyleDeclaration::getPropertyShorthand(const String&) |
4391 | { |
4392 | return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? |
4393 | } |
4394 | |
4395 | bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&) |
4396 | { |
4397 | return false; |
4398 | } |
4399 | |
4400 | ExceptionOr<void> CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&) |
4401 | { |
4402 | return Exception { NoModificationAllowedError }; |
4403 | } |
4404 | |
4405 | ExceptionOr<String> CSSComputedStyleDeclaration::removeProperty(const String&) |
4406 | { |
4407 | return Exception { NoModificationAllowedError }; |
4408 | } |
4409 | |
4410 | RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) |
4411 | { |
4412 | return getPropertyCSSValue(propertyID); |
4413 | } |
4414 | |
4415 | String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID) |
4416 | { |
4417 | return getPropertyValue(propertyID); |
4418 | } |
4419 | |
4420 | ExceptionOr<bool> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool) |
4421 | { |
4422 | return Exception { NoModificationAllowedError }; |
4423 | } |
4424 | |
4425 | Ref<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue() |
4426 | { |
4427 | static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition }; |
4428 | static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, CSSPropertyBackgroundClip }; |
4429 | |
4430 | auto list = CSSValueList::createSlashSeparated(); |
4431 | list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator))); |
4432 | list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator))); |
4433 | return list; |
4434 | } |
4435 | |
4436 | } // namespace WebCore |
4437 | |