1 | /* |
2 | * Copyright (C) 2004 Zack Rusin <zack@kde.org> |
3 | * Copyright (C) 2004-2017 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 | #if ENABLE(DASHBOARD_SUPPORT) |
88 | #include "DashboardRegion.h" |
89 | #endif |
90 | |
91 | namespace WebCore { |
92 | |
93 | WTF_MAKE_ISO_ALLOCATED_IMPL(CSSComputedStyleDeclaration); |
94 | |
95 | // List of all properties we know how to compute, omitting shorthands. |
96 | static const CSSPropertyID computedProperties[] = { |
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 | CSSPropertyBorderBottomColor, |
116 | CSSPropertyBorderBottomLeftRadius, |
117 | CSSPropertyBorderBottomRightRadius, |
118 | CSSPropertyBorderBottomStyle, |
119 | CSSPropertyBorderBottomWidth, |
120 | CSSPropertyBorderCollapse, |
121 | CSSPropertyBorderImageOutset, |
122 | CSSPropertyBorderImageRepeat, |
123 | CSSPropertyBorderImageSlice, |
124 | CSSPropertyBorderImageSource, |
125 | CSSPropertyBorderImageWidth, |
126 | CSSPropertyBorderLeftColor, |
127 | CSSPropertyBorderLeftStyle, |
128 | CSSPropertyBorderLeftWidth, |
129 | CSSPropertyBorderRightColor, |
130 | CSSPropertyBorderRightStyle, |
131 | CSSPropertyBorderRightWidth, |
132 | CSSPropertyBorderTopColor, |
133 | CSSPropertyBorderTopLeftRadius, |
134 | CSSPropertyBorderTopRightRadius, |
135 | CSSPropertyBorderTopStyle, |
136 | CSSPropertyBorderTopWidth, |
137 | CSSPropertyBottom, |
138 | CSSPropertyBoxShadow, |
139 | CSSPropertyBoxSizing, |
140 | CSSPropertyCaptionSide, |
141 | CSSPropertyCaretColor, |
142 | CSSPropertyClear, |
143 | CSSPropertyClip, |
144 | CSSPropertyColor, |
145 | CSSPropertyAppleColorFilter, |
146 | CSSPropertyCounterIncrement, |
147 | CSSPropertyCounterReset, |
148 | CSSPropertyContent, |
149 | CSSPropertyCursor, |
150 | CSSPropertyDirection, |
151 | CSSPropertyDisplay, |
152 | CSSPropertyEmptyCells, |
153 | CSSPropertyFloat, |
154 | CSSPropertyFontFamily, |
155 | CSSPropertyFontSize, |
156 | CSSPropertyFontStretch, |
157 | CSSPropertyFontStyle, |
158 | CSSPropertyFontSynthesis, |
159 | CSSPropertyFontVariant, |
160 | CSSPropertyFontWeight, |
161 | #if ENABLE(VARIATION_FONTS) |
162 | CSSPropertyFontOpticalSizing, |
163 | #endif |
164 | CSSPropertyHangingPunctuation, |
165 | CSSPropertyHeight, |
166 | #if ENABLE(CSS_IMAGE_ORIENTATION) |
167 | CSSPropertyImageOrientation, |
168 | #endif |
169 | CSSPropertyImageRendering, |
170 | #if ENABLE(CSS_IMAGE_RESOLUTION) |
171 | CSSPropertyImageResolution, |
172 | #endif |
173 | CSSPropertyLeft, |
174 | CSSPropertyLetterSpacing, |
175 | CSSPropertyLineHeight, |
176 | CSSPropertyListStyleImage, |
177 | CSSPropertyListStylePosition, |
178 | CSSPropertyListStyleType, |
179 | CSSPropertyMarginBottom, |
180 | CSSPropertyMarginLeft, |
181 | CSSPropertyMarginRight, |
182 | CSSPropertyMarginTop, |
183 | CSSPropertyMaxHeight, |
184 | CSSPropertyMaxWidth, |
185 | CSSPropertyMinHeight, |
186 | CSSPropertyMinWidth, |
187 | CSSPropertyObjectFit, |
188 | CSSPropertyObjectPosition, |
189 | CSSPropertyOpacity, |
190 | CSSPropertyOrphans, |
191 | CSSPropertyOutlineColor, |
192 | CSSPropertyOutlineOffset, |
193 | CSSPropertyOutlineStyle, |
194 | CSSPropertyOutlineWidth, |
195 | CSSPropertyOverflowWrap, |
196 | CSSPropertyOverflowX, |
197 | CSSPropertyOverflowY, |
198 | CSSPropertyPaddingBottom, |
199 | CSSPropertyPaddingLeft, |
200 | CSSPropertyPaddingRight, |
201 | CSSPropertyPaddingTop, |
202 | CSSPropertyPageBreakAfter, |
203 | CSSPropertyPageBreakBefore, |
204 | CSSPropertyPageBreakInside, |
205 | CSSPropertyPointerEvents, |
206 | CSSPropertyPosition, |
207 | CSSPropertyResize, |
208 | CSSPropertyRight, |
209 | CSSPropertySpeakAs, |
210 | CSSPropertyTableLayout, |
211 | CSSPropertyTabSize, |
212 | CSSPropertyTextAlign, |
213 | CSSPropertyTextDecoration, |
214 | #if ENABLE(CSS3_TEXT) |
215 | CSSPropertyWebkitTextAlignLast, |
216 | CSSPropertyWebkitTextJustify, |
217 | #endif // CSS3_TEXT |
218 | CSSPropertyTextDecorationLine, |
219 | CSSPropertyTextDecorationStyle, |
220 | CSSPropertyTextDecorationColor, |
221 | CSSPropertyTextDecorationSkip, |
222 | CSSPropertyTextUnderlinePosition, |
223 | CSSPropertyTextIndent, |
224 | CSSPropertyTextRendering, |
225 | CSSPropertyTextShadow, |
226 | CSSPropertyTextOverflow, |
227 | CSSPropertyTextTransform, |
228 | CSSPropertyTop, |
229 | CSSPropertyTransform, |
230 | CSSPropertyTransformBox, |
231 | CSSPropertyTransformOrigin, |
232 | CSSPropertyTransformStyle, |
233 | CSSPropertyTransitionDelay, |
234 | CSSPropertyTransitionDuration, |
235 | CSSPropertyTransitionProperty, |
236 | CSSPropertyTransitionTimingFunction, |
237 | CSSPropertyUnicodeBidi, |
238 | CSSPropertyVerticalAlign, |
239 | CSSPropertyVisibility, |
240 | CSSPropertyWhiteSpace, |
241 | CSSPropertyWidows, |
242 | CSSPropertyWidth, |
243 | CSSPropertyWillChange, |
244 | CSSPropertyWordBreak, |
245 | CSSPropertyWordSpacing, |
246 | CSSPropertyWordWrap, |
247 | #if ENABLE(CSS_SCROLL_SNAP) |
248 | CSSPropertyScrollSnapMargin, |
249 | CSSPropertyScrollSnapMarginLeft, |
250 | CSSPropertyScrollSnapMarginTop, |
251 | CSSPropertyScrollSnapMarginRight, |
252 | CSSPropertyScrollSnapMarginBottom, |
253 | CSSPropertyScrollPadding, |
254 | CSSPropertyScrollPaddingLeft, |
255 | CSSPropertyScrollPaddingTop, |
256 | CSSPropertyScrollPaddingRight, |
257 | CSSPropertyScrollPaddingBottom, |
258 | CSSPropertyScrollSnapType, |
259 | CSSPropertyScrollSnapAlign, |
260 | #endif |
261 | CSSPropertyZIndex, |
262 | CSSPropertyZoom, |
263 | CSSPropertyWebkitAppearance, |
264 | CSSPropertyWebkitBackfaceVisibility, |
265 | CSSPropertyWebkitBackgroundClip, |
266 | CSSPropertyWebkitBackgroundComposite, |
267 | CSSPropertyWebkitBackgroundOrigin, |
268 | CSSPropertyWebkitBackgroundSize, |
269 | #if ENABLE(CSS_COMPOSITING) |
270 | CSSPropertyMixBlendMode, |
271 | CSSPropertyIsolation, |
272 | #endif |
273 | CSSPropertyWebkitBorderFit, |
274 | CSSPropertyWebkitBorderHorizontalSpacing, |
275 | CSSPropertyWebkitBorderImage, |
276 | CSSPropertyWebkitBorderVerticalSpacing, |
277 | CSSPropertyWebkitBoxAlign, |
278 | #if ENABLE(CSS_BOX_DECORATION_BREAK) |
279 | CSSPropertyWebkitBoxDecorationBreak, |
280 | #endif |
281 | CSSPropertyWebkitBoxDirection, |
282 | CSSPropertyWebkitBoxFlex, |
283 | CSSPropertyWebkitBoxFlexGroup, |
284 | CSSPropertyWebkitBoxLines, |
285 | CSSPropertyWebkitBoxOrdinalGroup, |
286 | CSSPropertyWebkitBoxOrient, |
287 | CSSPropertyWebkitBoxPack, |
288 | CSSPropertyWebkitBoxReflect, |
289 | CSSPropertyWebkitBoxShadow, |
290 | CSSPropertyWebkitClipPath, |
291 | CSSPropertyWebkitColumnBreakAfter, |
292 | CSSPropertyWebkitColumnBreakBefore, |
293 | CSSPropertyWebkitColumnBreakInside, |
294 | CSSPropertyWebkitColumnAxis, |
295 | CSSPropertyColumnCount, |
296 | CSSPropertyColumnFill, |
297 | CSSPropertyColumnGap, |
298 | CSSPropertyRowGap, |
299 | CSSPropertyWebkitColumnProgression, |
300 | CSSPropertyColumnRuleColor, |
301 | CSSPropertyColumnRuleStyle, |
302 | CSSPropertyColumnRuleWidth, |
303 | CSSPropertyColumnSpan, |
304 | CSSPropertyColumnWidth, |
305 | #if ENABLE(CURSOR_VISIBILITY) |
306 | CSSPropertyWebkitCursorVisibility, |
307 | #endif |
308 | #if ENABLE(DASHBOARD_SUPPORT) |
309 | CSSPropertyWebkitDashboardRegion, |
310 | #endif |
311 | CSSPropertyAlignContent, |
312 | CSSPropertyAlignItems, |
313 | CSSPropertyAlignSelf, |
314 | CSSPropertyFilter, |
315 | CSSPropertyFlexBasis, |
316 | CSSPropertyFlexDirection, |
317 | CSSPropertyFlexFlow, |
318 | CSSPropertyFlexGrow, |
319 | CSSPropertyFlexShrink, |
320 | CSSPropertyFlexWrap, |
321 | CSSPropertyJustifyContent, |
322 | CSSPropertyJustifySelf, |
323 | CSSPropertyJustifyItems, |
324 | CSSPropertyPlaceContent, |
325 | CSSPropertyPlaceItems, |
326 | CSSPropertyPlaceSelf, |
327 | #if ENABLE(FILTERS_LEVEL_2) |
328 | CSSPropertyWebkitBackdropFilter, |
329 | #endif |
330 | CSSPropertyWebkitFontKerning, |
331 | CSSPropertyWebkitFontSmoothing, |
332 | CSSPropertyFontVariantLigatures, |
333 | CSSPropertyFontVariantPosition, |
334 | CSSPropertyFontVariantCaps, |
335 | CSSPropertyFontVariantNumeric, |
336 | CSSPropertyFontVariantAlternates, |
337 | CSSPropertyFontVariantEastAsian, |
338 | #if ENABLE(VARIATION_FONTS) |
339 | CSSPropertyFontVariationSettings, |
340 | #endif |
341 | CSSPropertyGridAutoColumns, |
342 | CSSPropertyGridAutoFlow, |
343 | CSSPropertyGridAutoRows, |
344 | CSSPropertyGridColumnEnd, |
345 | CSSPropertyGridColumnStart, |
346 | CSSPropertyGridTemplateAreas, |
347 | CSSPropertyGridTemplateColumns, |
348 | CSSPropertyGridTemplateRows, |
349 | CSSPropertyGridRowEnd, |
350 | CSSPropertyGridRowStart, |
351 | CSSPropertyWebkitHyphenateCharacter, |
352 | CSSPropertyWebkitHyphenateLimitAfter, |
353 | CSSPropertyWebkitHyphenateLimitBefore, |
354 | CSSPropertyWebkitHyphenateLimitLines, |
355 | CSSPropertyWebkitHyphens, |
356 | CSSPropertyWebkitInitialLetter, |
357 | CSSPropertyWebkitLineAlign, |
358 | CSSPropertyWebkitLineBoxContain, |
359 | CSSPropertyLineBreak, |
360 | CSSPropertyWebkitLineClamp, |
361 | CSSPropertyWebkitLineGrid, |
362 | CSSPropertyWebkitLineSnap, |
363 | CSSPropertyWebkitLocale, |
364 | CSSPropertyWebkitMarginBeforeCollapse, |
365 | CSSPropertyWebkitMarginAfterCollapse, |
366 | CSSPropertyWebkitMarqueeDirection, |
367 | CSSPropertyWebkitMarqueeIncrement, |
368 | CSSPropertyWebkitMarqueeRepetition, |
369 | CSSPropertyWebkitMarqueeStyle, |
370 | CSSPropertyWebkitMaskBoxImage, |
371 | CSSPropertyWebkitMaskBoxImageOutset, |
372 | CSSPropertyWebkitMaskBoxImageRepeat, |
373 | CSSPropertyWebkitMaskBoxImageSlice, |
374 | CSSPropertyWebkitMaskBoxImageSource, |
375 | CSSPropertyWebkitMaskBoxImageWidth, |
376 | CSSPropertyWebkitMaskClip, |
377 | CSSPropertyWebkitMaskComposite, |
378 | CSSPropertyWebkitMaskImage, |
379 | CSSPropertyWebkitMaskOrigin, |
380 | CSSPropertyWebkitMaskPosition, |
381 | CSSPropertyWebkitMaskRepeat, |
382 | CSSPropertyWebkitMaskSize, |
383 | CSSPropertyWebkitMaskSourceType, |
384 | CSSPropertyWebkitNbspMode, |
385 | CSSPropertyOrder, |
386 | #if ENABLE(OVERFLOW_SCROLLING_TOUCH) |
387 | CSSPropertyWebkitOverflowScrolling, |
388 | #endif |
389 | CSSPropertyPerspective, |
390 | CSSPropertyPerspectiveOrigin, |
391 | CSSPropertyWebkitPrintColorAdjust, |
392 | CSSPropertyWebkitRtlOrdering, |
393 | #if PLATFORM(IOS_FAMILY) |
394 | CSSPropertyWebkitTouchCallout, |
395 | #endif |
396 | #if ENABLE(TOUCH_EVENTS) |
397 | CSSPropertyWebkitTapHighlightColor, |
398 | #endif |
399 | CSSPropertyWebkitTextCombine, |
400 | CSSPropertyWebkitTextDecorationsInEffect, |
401 | CSSPropertyWebkitTextEmphasisColor, |
402 | CSSPropertyWebkitTextEmphasisPosition, |
403 | CSSPropertyWebkitTextEmphasisStyle, |
404 | CSSPropertyWebkitTextFillColor, |
405 | CSSPropertyWebkitTextOrientation, |
406 | CSSPropertyWebkitTextSecurity, |
407 | #if ENABLE(TEXT_AUTOSIZING) |
408 | CSSPropertyWebkitTextSizeAdjust, |
409 | #endif |
410 | CSSPropertyWebkitTextStrokeColor, |
411 | CSSPropertyWebkitTextStrokeWidth, |
412 | CSSPropertyWebkitTextZoom, |
413 | CSSPropertyWebkitTransformStyle, |
414 | CSSPropertyWebkitUserDrag, |
415 | CSSPropertyWebkitUserModify, |
416 | CSSPropertyWebkitUserSelect, |
417 | CSSPropertyShapeImageThreshold, |
418 | CSSPropertyShapeMargin, |
419 | CSSPropertyShapeOutside, |
420 | CSSPropertyShapeRendering, |
421 | CSSPropertyBufferedRendering, |
422 | CSSPropertyClipPath, |
423 | CSSPropertyClipRule, |
424 | CSSPropertyCx, |
425 | CSSPropertyCy, |
426 | CSSPropertyMask, |
427 | CSSPropertyMaskType, |
428 | CSSPropertyFloodColor, |
429 | CSSPropertyFloodOpacity, |
430 | CSSPropertyLightingColor, |
431 | CSSPropertyStopColor, |
432 | CSSPropertyStopOpacity, |
433 | CSSPropertyColorInterpolation, |
434 | CSSPropertyColorInterpolationFilters, |
435 | CSSPropertyColorRendering, |
436 | CSSPropertyFill, |
437 | CSSPropertyFillOpacity, |
438 | CSSPropertyFillRule, |
439 | CSSPropertyMarkerEnd, |
440 | CSSPropertyMarkerMid, |
441 | CSSPropertyMarkerStart, |
442 | CSSPropertyPaintOrder, |
443 | CSSPropertyR, |
444 | CSSPropertyRx, |
445 | CSSPropertyRy, |
446 | CSSPropertyStroke, |
447 | CSSPropertyStrokeColor, |
448 | CSSPropertyStrokeDasharray, |
449 | CSSPropertyStrokeDashoffset, |
450 | CSSPropertyStrokeLinecap, |
451 | CSSPropertyStrokeLinejoin, |
452 | CSSPropertyStrokeMiterlimit, |
453 | CSSPropertyStrokeOpacity, |
454 | CSSPropertyStrokeWidth, |
455 | #if ENABLE(DARK_MODE_CSS) |
456 | CSSPropertyColorScheme, |
457 | #endif |
458 | CSSPropertyAlignmentBaseline, |
459 | CSSPropertyBaselineShift, |
460 | CSSPropertyDominantBaseline, |
461 | CSSPropertyKerning, |
462 | CSSPropertyTextAnchor, |
463 | CSSPropertyWritingMode, |
464 | CSSPropertyGlyphOrientationHorizontal, |
465 | CSSPropertyGlyphOrientationVertical, |
466 | CSSPropertyVectorEffect, |
467 | CSSPropertyX, |
468 | CSSPropertyY |
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 AtomicString& 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 AtomicString& 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 | break; |
2789 | |
2790 | case CSSPropertyBackgroundColor: |
2791 | return cssValuePool.createColorValue(m_allowVisitedStyle? style.visitedDependentColor(CSSPropertyBackgroundColor) : style.backgroundColor()); |
2792 | case CSSPropertyBackgroundImage: |
2793 | case CSSPropertyWebkitMaskImage: { |
2794 | auto& layers = propertyID == CSSPropertyWebkitMaskImage ? style.maskLayers() : style.backgroundLayers(); |
2795 | if (!layers.next()) { |
2796 | if (layers.image()) |
2797 | return layers.image()->cssValue(); |
2798 | return cssValuePool.createIdentifierValue(CSSValueNone); |
2799 | } |
2800 | auto list = CSSValueList::createCommaSeparated(); |
2801 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) { |
2802 | if (currLayer->image()) |
2803 | list->append(currLayer->image()->cssValue()); |
2804 | else |
2805 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
2806 | } |
2807 | return list; |
2808 | } |
2809 | case CSSPropertyBackgroundSize: |
2810 | case CSSPropertyWebkitBackgroundSize: |
2811 | case CSSPropertyWebkitMaskSize: { |
2812 | auto& layers = propertyID == CSSPropertyWebkitMaskSize ? style.maskLayers() : style.backgroundLayers(); |
2813 | if (!layers.next()) |
2814 | return fillSizeToCSSValue(layers.size(), style); |
2815 | auto list = CSSValueList::createCommaSeparated(); |
2816 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2817 | list->append(fillSizeToCSSValue(currLayer->size(), style)); |
2818 | return list; |
2819 | } |
2820 | case CSSPropertyBackgroundRepeat: |
2821 | case CSSPropertyWebkitMaskRepeat: { |
2822 | auto& layers = propertyID == CSSPropertyWebkitMaskRepeat ? style.maskLayers() : style.backgroundLayers(); |
2823 | if (!layers.next()) |
2824 | return fillRepeatToCSSValue(layers.repeatX(), layers.repeatY()); |
2825 | auto list = CSSValueList::createCommaSeparated(); |
2826 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2827 | list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY())); |
2828 | return list; |
2829 | } |
2830 | case CSSPropertyWebkitMaskSourceType: { |
2831 | auto& layers = style.maskLayers(); |
2832 | if (!layers.next()) |
2833 | return fillSourceTypeToCSSValue(layers.maskSourceType()); |
2834 | auto list = CSSValueList::createCommaSeparated(); |
2835 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2836 | list->append(fillSourceTypeToCSSValue(currLayer->maskSourceType())); |
2837 | return list; |
2838 | } |
2839 | case CSSPropertyWebkitBackgroundComposite: |
2840 | case CSSPropertyWebkitMaskComposite: { |
2841 | auto& layers = propertyID == CSSPropertyWebkitMaskComposite ? style.maskLayers() : style.backgroundLayers(); |
2842 | if (!layers.next()) |
2843 | return cssValuePool.createValue(layers.composite()); |
2844 | auto list = CSSValueList::createCommaSeparated(); |
2845 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2846 | list->append(cssValuePool.createValue(currLayer->composite())); |
2847 | return list; |
2848 | } |
2849 | case CSSPropertyBackgroundAttachment: { |
2850 | auto& layers = style.backgroundLayers(); |
2851 | if (!layers.next()) |
2852 | return cssValuePool.createValue(layers.attachment()); |
2853 | auto list = CSSValueList::createCommaSeparated(); |
2854 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2855 | list->append(cssValuePool.createValue(currLayer->attachment())); |
2856 | return list; |
2857 | } |
2858 | case CSSPropertyBackgroundClip: |
2859 | case CSSPropertyBackgroundOrigin: |
2860 | case CSSPropertyWebkitBackgroundClip: |
2861 | case CSSPropertyWebkitBackgroundOrigin: |
2862 | case CSSPropertyWebkitMaskClip: |
2863 | case CSSPropertyWebkitMaskOrigin: { |
2864 | auto& layers = (propertyID == CSSPropertyWebkitMaskClip || propertyID == CSSPropertyWebkitMaskOrigin) ? style.maskLayers() : style.backgroundLayers(); |
2865 | bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip; |
2866 | if (!layers.next()) |
2867 | return cssValuePool.createValue(isClip ? layers.clip() : layers.origin()); |
2868 | auto list = CSSValueList::createCommaSeparated(); |
2869 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2870 | list->append(cssValuePool.createValue(isClip ? currLayer->clip() : currLayer->origin())); |
2871 | return list; |
2872 | } |
2873 | case CSSPropertyBackgroundPosition: |
2874 | case CSSPropertyWebkitMaskPosition: { |
2875 | auto& layers = propertyID == CSSPropertyWebkitMaskPosition ? style.maskLayers() : style.backgroundLayers(); |
2876 | if (!layers.next()) |
2877 | return createPositionListForLayer(propertyID, layers, style); |
2878 | |
2879 | auto list = CSSValueList::createCommaSeparated(); |
2880 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2881 | list->append(createPositionListForLayer(propertyID, *currLayer, style)); |
2882 | return list; |
2883 | } |
2884 | case CSSPropertyBackgroundPositionX: |
2885 | case CSSPropertyWebkitMaskPositionX: { |
2886 | auto& layers = propertyID == CSSPropertyWebkitMaskPositionX ? style.maskLayers() : style.backgroundLayers(); |
2887 | if (!layers.next()) |
2888 | return cssValuePool.createValue(layers.xPosition()); |
2889 | |
2890 | auto list = CSSValueList::createCommaSeparated(); |
2891 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2892 | list->append(cssValuePool.createValue(currLayer->xPosition())); |
2893 | |
2894 | return list; |
2895 | } |
2896 | case CSSPropertyBackgroundPositionY: |
2897 | case CSSPropertyWebkitMaskPositionY: { |
2898 | auto& layers = propertyID == CSSPropertyWebkitMaskPositionY ? style.maskLayers() : style.backgroundLayers(); |
2899 | if (!layers.next()) |
2900 | return cssValuePool.createValue(layers.yPosition()); |
2901 | |
2902 | auto list = CSSValueList::createCommaSeparated(); |
2903 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
2904 | list->append(cssValuePool.createValue(currLayer->yPosition())); |
2905 | |
2906 | return list; |
2907 | } |
2908 | case CSSPropertyBorderCollapse: |
2909 | if (style.borderCollapse() == BorderCollapse::Collapse) |
2910 | return cssValuePool.createIdentifierValue(CSSValueCollapse); |
2911 | return cssValuePool.createIdentifierValue(CSSValueSeparate); |
2912 | case CSSPropertyBorderSpacing: { |
2913 | auto list = CSSValueList::createSpaceSeparated(); |
2914 | list->append(zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style)); |
2915 | list->append(zoomAdjustedPixelValue(style.verticalBorderSpacing(), style)); |
2916 | return list; |
2917 | } |
2918 | case CSSPropertyWebkitBorderHorizontalSpacing: |
2919 | return zoomAdjustedPixelValue(style.horizontalBorderSpacing(), style); |
2920 | case CSSPropertyWebkitBorderVerticalSpacing: |
2921 | return zoomAdjustedPixelValue(style.verticalBorderSpacing(), style); |
2922 | case CSSPropertyBorderImageSource: |
2923 | if (style.borderImageSource()) |
2924 | return style.borderImageSource()->cssValue(); |
2925 | return cssValuePool.createIdentifierValue(CSSValueNone); |
2926 | case CSSPropertyBorderTopColor: |
2927 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderTopColor)) : currentColorOrValidColor(&style, style.borderTopColor()); |
2928 | case CSSPropertyBorderRightColor: |
2929 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderRightColor)) : currentColorOrValidColor(&style, style.borderRightColor()); |
2930 | case CSSPropertyBorderBottomColor: |
2931 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderBottomColor)) : currentColorOrValidColor(&style, style.borderBottomColor()); |
2932 | case CSSPropertyBorderLeftColor: |
2933 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyBorderLeftColor)) : currentColorOrValidColor(&style, style.borderLeftColor()); |
2934 | case CSSPropertyBorderTopStyle: |
2935 | return cssValuePool.createValue(style.borderTopStyle()); |
2936 | case CSSPropertyBorderRightStyle: |
2937 | return cssValuePool.createValue(style.borderRightStyle()); |
2938 | case CSSPropertyBorderBottomStyle: |
2939 | return cssValuePool.createValue(style.borderBottomStyle()); |
2940 | case CSSPropertyBorderLeftStyle: |
2941 | return cssValuePool.createValue(style.borderLeftStyle()); |
2942 | case CSSPropertyBorderTopWidth: |
2943 | return zoomAdjustedPixelValue(style.borderTopWidth(), style); |
2944 | case CSSPropertyBorderRightWidth: |
2945 | return zoomAdjustedPixelValue(style.borderRightWidth(), style); |
2946 | case CSSPropertyBorderBottomWidth: |
2947 | return zoomAdjustedPixelValue(style.borderBottomWidth(), style); |
2948 | case CSSPropertyBorderLeftWidth: |
2949 | return zoomAdjustedPixelValue(style.borderLeftWidth(), style); |
2950 | case CSSPropertyBottom: |
2951 | return positionOffsetValue(style, CSSPropertyBottom, renderer); |
2952 | case CSSPropertyWebkitBoxAlign: |
2953 | return cssValuePool.createValue(style.boxAlign()); |
2954 | #if ENABLE(CSS_BOX_DECORATION_BREAK) |
2955 | case CSSPropertyWebkitBoxDecorationBreak: |
2956 | if (style.boxDecorationBreak() == BoxDecorationBreak::Slice) |
2957 | return cssValuePool.createIdentifierValue(CSSValueSlice); |
2958 | return cssValuePool.createIdentifierValue(CSSValueClone); |
2959 | #endif |
2960 | case CSSPropertyWebkitBoxDirection: |
2961 | return cssValuePool.createValue(style.boxDirection()); |
2962 | case CSSPropertyWebkitBoxFlex: |
2963 | return cssValuePool.createValue(style.boxFlex(), CSSPrimitiveValue::CSS_NUMBER); |
2964 | case CSSPropertyWebkitBoxFlexGroup: |
2965 | return cssValuePool.createValue(style.boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER); |
2966 | case CSSPropertyWebkitBoxLines: |
2967 | return cssValuePool.createValue(style.boxLines()); |
2968 | case CSSPropertyWebkitBoxOrdinalGroup: |
2969 | return cssValuePool.createValue(style.boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER); |
2970 | case CSSPropertyWebkitBoxOrient: |
2971 | return cssValuePool.createValue(style.boxOrient()); |
2972 | case CSSPropertyWebkitBoxPack: |
2973 | return cssValuePool.createValue(style.boxPack()); |
2974 | case CSSPropertyWebkitBoxReflect: |
2975 | return valueForReflection(style.boxReflect(), style); |
2976 | case CSSPropertyBoxShadow: |
2977 | case CSSPropertyWebkitBoxShadow: |
2978 | return valueForShadow(style.boxShadow(), propertyID, style); |
2979 | case CSSPropertyCaptionSide: |
2980 | return cssValuePool.createValue(style.captionSide()); |
2981 | case CSSPropertyCaretColor: |
2982 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyCaretColor)) : currentColorOrValidColor(&style, style.caretColor()); |
2983 | case CSSPropertyClear: |
2984 | return cssValuePool.createValue(style.clear()); |
2985 | case CSSPropertyColor: |
2986 | return cssValuePool.createColorValue(m_allowVisitedStyle ? style.visitedDependentColor(CSSPropertyColor) : style.color()); |
2987 | case CSSPropertyWebkitPrintColorAdjust: |
2988 | return cssValuePool.createValue(style.printColorAdjust()); |
2989 | case CSSPropertyWebkitColumnAxis: |
2990 | return cssValuePool.createValue(style.columnAxis()); |
2991 | case CSSPropertyColumnCount: |
2992 | if (style.hasAutoColumnCount()) |
2993 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
2994 | return cssValuePool.createValue(style.columnCount(), CSSPrimitiveValue::CSS_NUMBER); |
2995 | case CSSPropertyColumnFill: |
2996 | return cssValuePool.createValue(style.columnFill()); |
2997 | case CSSPropertyColumnGap: |
2998 | if (style.columnGap().isNormal()) |
2999 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3000 | return zoomAdjustedPixelValueForLength(style.columnGap().length(), style); |
3001 | case CSSPropertyRowGap: |
3002 | if (style.rowGap().isNormal()) |
3003 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3004 | return zoomAdjustedPixelValueForLength(style.rowGap().length(), style); |
3005 | case CSSPropertyWebkitColumnProgression: |
3006 | return cssValuePool.createValue(style.columnProgression()); |
3007 | case CSSPropertyColumnRuleColor: |
3008 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.columnRuleColor()); |
3009 | case CSSPropertyColumnRuleStyle: |
3010 | return cssValuePool.createValue(style.columnRuleStyle()); |
3011 | case CSSPropertyColumnRuleWidth: |
3012 | return zoomAdjustedPixelValue(style.columnRuleWidth(), style); |
3013 | case CSSPropertyColumnSpan: |
3014 | return cssValuePool.createIdentifierValue(style.columnSpan() == ColumnSpan::All ? CSSValueAll : CSSValueNone); |
3015 | case CSSPropertyWebkitColumnBreakAfter: |
3016 | return cssValuePool.createValue(convertToColumnBreak(style.breakAfter())); |
3017 | case CSSPropertyWebkitColumnBreakBefore: |
3018 | return cssValuePool.createValue(convertToColumnBreak(style.breakBefore())); |
3019 | case CSSPropertyWebkitColumnBreakInside: |
3020 | return cssValuePool.createValue(convertToColumnBreak(style.breakInside())); |
3021 | case CSSPropertyColumnWidth: |
3022 | if (style.hasAutoColumnWidth()) |
3023 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3024 | return zoomAdjustedPixelValue(style.columnWidth(), style); |
3025 | case CSSPropertyTabSize: |
3026 | return cssValuePool.createValue(style.tabSize(), CSSPrimitiveValue::CSS_NUMBER); |
3027 | case CSSPropertyCursor: { |
3028 | RefPtr<CSSValueList> list; |
3029 | auto* cursors = style.cursors(); |
3030 | if (cursors && cursors->size() > 0) { |
3031 | list = CSSValueList::createCommaSeparated(); |
3032 | for (unsigned i = 0; i < cursors->size(); ++i) |
3033 | if (StyleImage* image = cursors->at(i).image()) |
3034 | list->append(image->cssValue()); |
3035 | } |
3036 | auto value = cssValuePool.createValue(style.cursor()); |
3037 | if (list) { |
3038 | list->append(WTFMove(value)); |
3039 | return list; |
3040 | } |
3041 | return value; |
3042 | } |
3043 | #if ENABLE(CURSOR_VISIBILITY) |
3044 | case CSSPropertyWebkitCursorVisibility: |
3045 | return cssValuePool.createValue(style.cursorVisibility()); |
3046 | #endif |
3047 | case CSSPropertyDirection: |
3048 | return cssValuePool.createValue(style.direction()); |
3049 | case CSSPropertyDisplay: |
3050 | return cssValuePool.createValue(style.display()); |
3051 | case CSSPropertyEmptyCells: |
3052 | return cssValuePool.createValue(style.emptyCells()); |
3053 | case CSSPropertyAlignContent: |
3054 | return valueForContentPositionAndDistributionWithOverflowAlignment(style.alignContent()); |
3055 | case CSSPropertyAlignItems: |
3056 | return valueForItemPositionWithOverflowAlignment(style.alignItems()); |
3057 | case CSSPropertyAlignSelf: |
3058 | return valueForItemPositionWithOverflowAlignment(style.alignSelf()); |
3059 | case CSSPropertyFlex: |
3060 | return getCSSPropertyValuesForShorthandProperties(flexShorthand()); |
3061 | case CSSPropertyFlexBasis: |
3062 | return cssValuePool.createValue(style.flexBasis(), style); |
3063 | case CSSPropertyFlexDirection: |
3064 | return cssValuePool.createValue(style.flexDirection()); |
3065 | case CSSPropertyFlexFlow: |
3066 | return getCSSPropertyValuesForShorthandProperties(flexFlowShorthand()); |
3067 | case CSSPropertyFlexGrow: |
3068 | return cssValuePool.createValue(style.flexGrow()); |
3069 | case CSSPropertyFlexShrink: |
3070 | return cssValuePool.createValue(style.flexShrink()); |
3071 | case CSSPropertyFlexWrap: |
3072 | return cssValuePool.createValue(style.flexWrap()); |
3073 | case CSSPropertyJustifyContent: |
3074 | return valueForContentPositionAndDistributionWithOverflowAlignment(style.justifyContent()); |
3075 | case CSSPropertyJustifyItems: |
3076 | return valueForItemPositionWithOverflowAlignment(style.justifyItems()); |
3077 | case CSSPropertyJustifySelf: |
3078 | return valueForItemPositionWithOverflowAlignment(style.justifySelf()); |
3079 | case CSSPropertyPlaceContent: |
3080 | return getCSSPropertyValuesForShorthandProperties(placeContentShorthand()); |
3081 | case CSSPropertyPlaceItems: |
3082 | return getCSSPropertyValuesForShorthandProperties(placeItemsShorthand()); |
3083 | case CSSPropertyPlaceSelf: |
3084 | return getCSSPropertyValuesForShorthandProperties(placeSelfShorthand()); |
3085 | case CSSPropertyOrder: |
3086 | return cssValuePool.createValue(style.order(), CSSPrimitiveValue::CSS_NUMBER); |
3087 | case CSSPropertyFloat: |
3088 | if (style.display() != DisplayType::None && style.hasOutOfFlowPosition()) |
3089 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3090 | return cssValuePool.createValue(style.floating()); |
3091 | case CSSPropertyFont: { |
3092 | auto computedFont = fontShorthandValueForSelectionProperties(style.fontDescription()); |
3093 | computedFont->size = fontSizeFromStyle(style); |
3094 | computedFont->lineHeight = lineHeightFromStyle(style); |
3095 | computedFont->family = fontFamilyListFromStyle(style); |
3096 | return computedFont; |
3097 | } |
3098 | case CSSPropertyFontFamily: |
3099 | return fontFamilyFromStyle(style); |
3100 | case CSSPropertyFontSize: |
3101 | return fontSizeFromStyle(style); |
3102 | case CSSPropertyFontStyle: |
3103 | return fontStyleFromStyle(style); |
3104 | case CSSPropertyFontStretch: |
3105 | return fontStretchFromStyle(style); |
3106 | case CSSPropertyFontVariant: |
3107 | return fontVariantFromStyle(style); |
3108 | case CSSPropertyFontWeight: |
3109 | return fontWeightFromStyle(style); |
3110 | case CSSPropertyFontSynthesis: |
3111 | return fontSynthesisFromStyle(style); |
3112 | case CSSPropertyFontFeatureSettings: { |
3113 | const FontFeatureSettings& featureSettings = style.fontDescription().featureSettings(); |
3114 | if (!featureSettings.size()) |
3115 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3116 | auto list = CSSValueList::createCommaSeparated(); |
3117 | for (auto& feature : featureSettings) |
3118 | list->append(CSSFontFeatureValue::create(FontTag(feature.tag()), feature.value())); |
3119 | return list; |
3120 | } |
3121 | #if ENABLE(VARIATION_FONTS) |
3122 | case CSSPropertyFontVariationSettings: { |
3123 | const FontVariationSettings& variationSettings = style.fontDescription().variationSettings(); |
3124 | if (variationSettings.isEmpty()) |
3125 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3126 | auto list = CSSValueList::createCommaSeparated(); |
3127 | for (auto& feature : variationSettings) |
3128 | list->append(CSSFontVariationValue::create(feature.tag(), feature.value())); |
3129 | return list; |
3130 | } |
3131 | case CSSPropertyFontOpticalSizing: |
3132 | return cssValuePool.createValue(style.fontDescription().opticalSizing()); |
3133 | #endif |
3134 | case CSSPropertyGridAutoFlow: { |
3135 | auto list = CSSValueList::createSpaceSeparated(); |
3136 | ASSERT(style.isGridAutoFlowDirectionRow() || style.isGridAutoFlowDirectionColumn()); |
3137 | if (style.isGridAutoFlowDirectionRow()) |
3138 | list->append(cssValuePool.createIdentifierValue(CSSValueRow)); |
3139 | else |
3140 | list->append(cssValuePool.createIdentifierValue(CSSValueColumn)); |
3141 | |
3142 | if (style.isGridAutoFlowAlgorithmDense()) |
3143 | list->append(cssValuePool.createIdentifierValue(CSSValueDense)); |
3144 | |
3145 | return list; |
3146 | } |
3147 | |
3148 | // Specs mention that getComputedStyle() should return the used value of the property instead of the computed |
3149 | // one for grid-template-{rows|columns} but not for the grid-auto-{rows|columns} as things like |
3150 | // grid-auto-columns: 2fr; cannot be resolved to a value in pixels as the '2fr' means very different things |
3151 | // depending on the size of the explicit grid or the number of implicit tracks added to the grid. See |
3152 | // http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html |
3153 | case CSSPropertyGridAutoColumns: |
3154 | return valueForGridTrackSizeList(ForColumns, style); |
3155 | case CSSPropertyGridAutoRows: |
3156 | return valueForGridTrackSizeList(ForRows, style); |
3157 | |
3158 | case CSSPropertyGridTemplateColumns: |
3159 | return valueForGridTrackList(ForColumns, renderer, style); |
3160 | case CSSPropertyGridTemplateRows: |
3161 | return valueForGridTrackList(ForRows, renderer, style); |
3162 | |
3163 | case CSSPropertyGridColumnStart: |
3164 | return valueForGridPosition(style.gridItemColumnStart()); |
3165 | case CSSPropertyGridColumnEnd: |
3166 | return valueForGridPosition(style.gridItemColumnEnd()); |
3167 | case CSSPropertyGridRowStart: |
3168 | return valueForGridPosition(style.gridItemRowStart()); |
3169 | case CSSPropertyGridRowEnd: |
3170 | return valueForGridPosition(style.gridItemRowEnd()); |
3171 | case CSSPropertyGridArea: |
3172 | return getCSSPropertyValuesForGridShorthand(gridAreaShorthand()); |
3173 | case CSSPropertyGridTemplate: |
3174 | return getCSSPropertyValuesForGridShorthand(gridTemplateShorthand()); |
3175 | case CSSPropertyGrid: |
3176 | return getCSSPropertyValuesForGridShorthand(gridShorthand()); |
3177 | case CSSPropertyGridColumn: |
3178 | return getCSSPropertyValuesForGridShorthand(gridColumnShorthand()); |
3179 | case CSSPropertyGridRow: |
3180 | return getCSSPropertyValuesForGridShorthand(gridRowShorthand()); |
3181 | case CSSPropertyGridTemplateAreas: |
3182 | if (!style.namedGridAreaRowCount()) { |
3183 | ASSERT(!style.namedGridAreaColumnCount()); |
3184 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3185 | } |
3186 | return CSSGridTemplateAreasValue::create(style.namedGridArea(), style.namedGridAreaRowCount(), style.namedGridAreaColumnCount()); |
3187 | case CSSPropertyGap: |
3188 | return getCSSPropertyValuesForShorthandProperties(gapShorthand()); |
3189 | case CSSPropertyHeight: |
3190 | if (renderer && !renderer->isRenderSVGModelObject()) { |
3191 | // According to http://www.w3.org/TR/CSS2/visudet.html#the-height-property, |
3192 | // the "height" property does not apply for non-replaced inline elements. |
3193 | if (isNonReplacedInline(*renderer)) |
3194 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3195 | return zoomAdjustedPixelValue(sizingBox(*renderer).height(), style); |
3196 | } |
3197 | return zoomAdjustedPixelValueForLength(style.height(), style); |
3198 | case CSSPropertyWebkitHyphens: |
3199 | return cssValuePool.createValue(style.hyphens()); |
3200 | case CSSPropertyWebkitHyphenateCharacter: |
3201 | if (style.hyphenationString().isNull()) |
3202 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3203 | return cssValuePool.createValue(style.hyphenationString(), CSSPrimitiveValue::CSS_STRING); |
3204 | case CSSPropertyWebkitHyphenateLimitAfter: |
3205 | if (style.hyphenationLimitAfter() < 0) |
3206 | return CSSPrimitiveValue::createIdentifier(CSSValueAuto); |
3207 | return CSSPrimitiveValue::create(style.hyphenationLimitAfter(), CSSPrimitiveValue::CSS_NUMBER); |
3208 | case CSSPropertyWebkitHyphenateLimitBefore: |
3209 | if (style.hyphenationLimitBefore() < 0) |
3210 | return CSSPrimitiveValue::createIdentifier(CSSValueAuto); |
3211 | return CSSPrimitiveValue::create(style.hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER); |
3212 | case CSSPropertyWebkitHyphenateLimitLines: |
3213 | if (style.hyphenationLimitLines() < 0) |
3214 | return CSSPrimitiveValue::createIdentifier(CSSValueNoLimit); |
3215 | return CSSPrimitiveValue::create(style.hyphenationLimitLines(), CSSPrimitiveValue::CSS_NUMBER); |
3216 | case CSSPropertyWebkitBorderFit: |
3217 | if (style.borderFit() == BorderFit::Border) |
3218 | return cssValuePool.createIdentifierValue(CSSValueBorder); |
3219 | return cssValuePool.createIdentifierValue(CSSValueLines); |
3220 | #if ENABLE(CSS_IMAGE_ORIENTATION) |
3221 | case CSSPropertyImageOrientation: |
3222 | return cssValuePool.createValue(style.imageOrientation()); |
3223 | #endif |
3224 | case CSSPropertyImageRendering: |
3225 | return CSSPrimitiveValue::create(style.imageRendering()); |
3226 | #if ENABLE(CSS_IMAGE_RESOLUTION) |
3227 | case CSSPropertyImageResolution: |
3228 | return cssValuePool.createValue(style.imageResolution(), CSSPrimitiveValue::CSS_DPPX); |
3229 | #endif |
3230 | case CSSPropertyLeft: |
3231 | return positionOffsetValue(style, CSSPropertyLeft, renderer); |
3232 | case CSSPropertyLetterSpacing: |
3233 | if (!style.letterSpacing()) |
3234 | return cssValuePool.createIdentifierValue(CSSValueNormal); |
3235 | return zoomAdjustedPixelValue(style.letterSpacing(), style); |
3236 | case CSSPropertyWebkitLineClamp: |
3237 | if (style.lineClamp().isNone()) |
3238 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3239 | return cssValuePool.createValue(style.lineClamp().value(), style.lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER); |
3240 | case CSSPropertyLineHeight: |
3241 | return lineHeightFromStyle(style); |
3242 | case CSSPropertyListStyleImage: |
3243 | if (style.listStyleImage()) |
3244 | return style.listStyleImage()->cssValue(); |
3245 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3246 | case CSSPropertyListStylePosition: |
3247 | return cssValuePool.createValue(style.listStylePosition()); |
3248 | case CSSPropertyListStyleType: |
3249 | return cssValuePool.createValue(style.listStyleType()); |
3250 | case CSSPropertyWebkitLocale: |
3251 | if (style.locale().isNull()) |
3252 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3253 | return cssValuePool.createValue(style.locale(), CSSPrimitiveValue::CSS_STRING); |
3254 | case CSSPropertyMarginTop: |
3255 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginTop, &RenderBoxModelObject::marginTop>(style, renderer); |
3256 | case CSSPropertyMarginRight: { |
3257 | Length marginRight = style.marginRight(); |
3258 | if (marginRight.isFixed() || !is<RenderBox>(renderer)) |
3259 | return zoomAdjustedPixelValueForLength(marginRight, style); |
3260 | float value; |
3261 | if (marginRight.isPercentOrCalculated()) { |
3262 | // RenderBox gives a marginRight() that is the distance between the right-edge of the child box |
3263 | // and the right-edge of the containing box, when display == DisplayType::Block. Let's calculate the absolute |
3264 | // value of the specified margin-right % instead of relying on RenderBox's marginRight() value. |
3265 | value = minimumValueForLength(marginRight, downcast<RenderBox>(*renderer).containingBlockLogicalWidthForContent()); |
3266 | } else |
3267 | value = downcast<RenderBox>(*renderer).marginRight(); |
3268 | return zoomAdjustedPixelValue(value, style); |
3269 | } |
3270 | case CSSPropertyMarginBottom: |
3271 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginBottom, &RenderBoxModelObject::marginBottom>(style, renderer); |
3272 | case CSSPropertyMarginLeft: |
3273 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::marginLeft, &RenderBoxModelObject::marginLeft>(style, renderer); |
3274 | case CSSPropertyWebkitMarqueeDirection: |
3275 | return cssValuePool.createValue(style.marqueeDirection()); |
3276 | case CSSPropertyWebkitMarqueeIncrement: |
3277 | return cssValuePool.createValue(style.marqueeIncrement()); |
3278 | case CSSPropertyWebkitMarqueeRepetition: |
3279 | if (style.marqueeLoopCount() < 0) |
3280 | return cssValuePool.createIdentifierValue(CSSValueInfinite); |
3281 | return cssValuePool.createValue(style.marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER); |
3282 | case CSSPropertyWebkitMarqueeStyle: |
3283 | return cssValuePool.createValue(style.marqueeBehavior()); |
3284 | case CSSPropertyWebkitUserModify: |
3285 | return cssValuePool.createValue(style.userModify()); |
3286 | case CSSPropertyMaxHeight: { |
3287 | const Length& maxHeight = style.maxHeight(); |
3288 | if (maxHeight.isUndefined()) |
3289 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3290 | return zoomAdjustedPixelValueForLength(maxHeight, style); |
3291 | } |
3292 | case CSSPropertyMaxWidth: { |
3293 | const Length& maxWidth = style.maxWidth(); |
3294 | if (maxWidth.isUndefined()) |
3295 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3296 | return zoomAdjustedPixelValueForLength(maxWidth, style); |
3297 | } |
3298 | case CSSPropertyMinHeight: |
3299 | if (style.minHeight().isAuto()) { |
3300 | auto* styledElement = this->styledElement(); |
3301 | if (styledElement && isFlexOrGrid(styledElement->parentNode())) |
3302 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3303 | return zoomAdjustedPixelValue(0, style); |
3304 | } |
3305 | return zoomAdjustedPixelValueForLength(style.minHeight(), style); |
3306 | case CSSPropertyMinWidth: |
3307 | if (style.minWidth().isAuto()) { |
3308 | auto* styledElement = this->styledElement(); |
3309 | if (styledElement && isFlexOrGrid(styledElement->parentNode())) |
3310 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3311 | return zoomAdjustedPixelValue(0, style); |
3312 | } |
3313 | return zoomAdjustedPixelValueForLength(style.minWidth(), style); |
3314 | case CSSPropertyObjectFit: |
3315 | return cssValuePool.createValue(style.objectFit()); |
3316 | case CSSPropertyObjectPosition: { |
3317 | auto list = CSSValueList::createSpaceSeparated(); |
3318 | list->append(zoomAdjustedPixelValueForLength(style.objectPosition().x(), style)); |
3319 | list->append(zoomAdjustedPixelValueForLength(style.objectPosition().y(), style)); |
3320 | return list; |
3321 | } |
3322 | case CSSPropertyOpacity: |
3323 | return cssValuePool.createValue(style.opacity(), CSSPrimitiveValue::CSS_NUMBER); |
3324 | case CSSPropertyOrphans: |
3325 | if (style.hasAutoOrphans()) |
3326 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3327 | return cssValuePool.createValue(style.orphans(), CSSPrimitiveValue::CSS_NUMBER); |
3328 | case CSSPropertyOutlineColor: |
3329 | return m_allowVisitedStyle ? cssValuePool.createColorValue(style.visitedDependentColor(CSSPropertyOutlineColor)) : currentColorOrValidColor(&style, style.outlineColor()); |
3330 | case CSSPropertyOutlineOffset: |
3331 | return zoomAdjustedPixelValue(style.outlineOffset(), style); |
3332 | case CSSPropertyOutlineStyle: |
3333 | if (style.outlineStyleIsAuto() == OutlineIsAuto::On) |
3334 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3335 | return cssValuePool.createValue(style.outlineStyle()); |
3336 | case CSSPropertyOutlineWidth: |
3337 | return zoomAdjustedPixelValue(style.outlineWidth(), style); |
3338 | case CSSPropertyOverflow: |
3339 | return cssValuePool.createValue(std::max(style.overflowX(), style.overflowY())); |
3340 | case CSSPropertyOverflowWrap: |
3341 | return cssValuePool.createValue(style.overflowWrap()); |
3342 | case CSSPropertyOverflowX: |
3343 | return cssValuePool.createValue(style.overflowX()); |
3344 | case CSSPropertyOverflowY: |
3345 | return cssValuePool.createValue(style.overflowY()); |
3346 | case CSSPropertyPaddingTop: |
3347 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingTop, &RenderBoxModelObject::computedCSSPaddingTop>(style, renderer); |
3348 | case CSSPropertyPaddingRight: |
3349 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingRight, &RenderBoxModelObject::computedCSSPaddingRight>(style, renderer); |
3350 | case CSSPropertyPaddingBottom: |
3351 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingBottom, &RenderBoxModelObject::computedCSSPaddingBottom>(style, renderer); |
3352 | case CSSPropertyPaddingLeft: |
3353 | return zoomAdjustedPaddingOrMarginPixelValue<&RenderStyle::paddingLeft, &RenderBoxModelObject::computedCSSPaddingLeft>(style, renderer); |
3354 | case CSSPropertyPageBreakAfter: |
3355 | return cssValuePool.createValue(convertToPageBreak(style.breakAfter())); |
3356 | case CSSPropertyPageBreakBefore: |
3357 | return cssValuePool.createValue(convertToPageBreak(style.breakBefore())); |
3358 | case CSSPropertyPageBreakInside: |
3359 | return cssValuePool.createValue(convertToPageBreak(style.breakInside())); |
3360 | case CSSPropertyBreakAfter: |
3361 | return cssValuePool.createValue(style.breakAfter()); |
3362 | case CSSPropertyBreakBefore: |
3363 | return cssValuePool.createValue(style.breakBefore()); |
3364 | case CSSPropertyBreakInside: |
3365 | return cssValuePool.createValue(style.breakInside()); |
3366 | case CSSPropertyHangingPunctuation: |
3367 | return hangingPunctuationToCSSValue(style.hangingPunctuation()); |
3368 | case CSSPropertyPosition: |
3369 | return cssValuePool.createValue(style.position()); |
3370 | case CSSPropertyRight: |
3371 | return positionOffsetValue(style, CSSPropertyRight, renderer); |
3372 | case CSSPropertyWebkitRubyPosition: |
3373 | return cssValuePool.createValue(style.rubyPosition()); |
3374 | case CSSPropertyTableLayout: |
3375 | return cssValuePool.createValue(style.tableLayout()); |
3376 | case CSSPropertyTextAlign: |
3377 | return cssValuePool.createValue(style.textAlign()); |
3378 | case CSSPropertyTextDecoration: |
3379 | return renderTextDecorationFlagsToCSSValue(style.textDecoration()); |
3380 | #if ENABLE(CSS3_TEXT) |
3381 | case CSSPropertyWebkitTextAlignLast: |
3382 | return cssValuePool.createValue(style.textAlignLast()); |
3383 | case CSSPropertyWebkitTextJustify: |
3384 | return cssValuePool.createValue(style.textJustify()); |
3385 | #endif // CSS3_TEXT |
3386 | case CSSPropertyWebkitTextDecoration: |
3387 | return getCSSPropertyValuesForShorthandProperties(webkitTextDecorationShorthand()); |
3388 | case CSSPropertyTextDecorationLine: |
3389 | return renderTextDecorationFlagsToCSSValue(style.textDecoration()); |
3390 | case CSSPropertyTextDecorationStyle: |
3391 | return renderTextDecorationStyleFlagsToCSSValue(style.textDecorationStyle()); |
3392 | case CSSPropertyTextDecorationColor: |
3393 | return currentColorOrValidColor(&style, style.textDecorationColor()); |
3394 | case CSSPropertyTextDecorationSkip: |
3395 | return renderTextDecorationSkipFlagsToCSSValue(style.textDecorationSkip()); |
3396 | case CSSPropertyTextUnderlinePosition: |
3397 | return cssValuePool.createValue(style.textUnderlinePosition()); |
3398 | case CSSPropertyTextUnderlineOffset: |
3399 | return textUnderlineOffsetToCSSValue(style.textUnderlineOffset()); |
3400 | case CSSPropertyTextDecorationThickness: |
3401 | return textDecorationThicknessToCSSValue(style.textDecorationThickness()); |
3402 | case CSSPropertyWebkitTextDecorationsInEffect: |
3403 | return renderTextDecorationFlagsToCSSValue(style.textDecorationsInEffect()); |
3404 | case CSSPropertyWebkitTextFillColor: |
3405 | return currentColorOrValidColor(&style, style.textFillColor()); |
3406 | case CSSPropertyWebkitTextEmphasisColor: |
3407 | return currentColorOrValidColor(&style, style.textEmphasisColor()); |
3408 | case CSSPropertyWebkitTextEmphasisPosition: |
3409 | return renderEmphasisPositionFlagsToCSSValue(style.textEmphasisPosition()); |
3410 | case CSSPropertyWebkitTextEmphasisStyle: |
3411 | switch (style.textEmphasisMark()) { |
3412 | case TextEmphasisMark::None: |
3413 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3414 | case TextEmphasisMark::Custom: |
3415 | return cssValuePool.createValue(style.textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING); |
3416 | case TextEmphasisMark::Auto: |
3417 | ASSERT_NOT_REACHED(); |
3418 | #if ASSERT_DISABLED |
3419 | FALLTHROUGH; |
3420 | #endif |
3421 | case TextEmphasisMark::Dot: |
3422 | case TextEmphasisMark::Circle: |
3423 | case TextEmphasisMark::DoubleCircle: |
3424 | case TextEmphasisMark::Triangle: |
3425 | case TextEmphasisMark::Sesame: |
3426 | auto list = CSSValueList::createSpaceSeparated(); |
3427 | list->append(cssValuePool.createValue(style.textEmphasisFill())); |
3428 | list->append(cssValuePool.createValue(style.textEmphasisMark())); |
3429 | return list; |
3430 | } |
3431 | RELEASE_ASSERT_NOT_REACHED(); |
3432 | case CSSPropertyTextIndent: { |
3433 | // If CSS3_TEXT is disabled or text-indent has only one value(<length> | <percentage>), |
3434 | // getPropertyCSSValue() returns CSSValue. |
3435 | auto textIndent = zoomAdjustedPixelValueForLength(style.textIndent(), style); |
3436 | #if ENABLE(CSS3_TEXT) |
3437 | // If CSS3_TEXT is enabled and text-indent has -webkit-each-line or -webkit-hanging, |
3438 | // getPropertyCSSValue() returns CSSValueList. |
3439 | if (style.textIndentLine() == TextIndentLine::EachLine || style.textIndentType() == TextIndentType::Hanging) { |
3440 | auto list = CSSValueList::createSpaceSeparated(); |
3441 | list->append(WTFMove(textIndent)); |
3442 | if (style.textIndentLine() == TextIndentLine::EachLine) |
3443 | list->append(cssValuePool.createIdentifierValue(CSSValueWebkitEachLine)); |
3444 | if (style.textIndentType() == TextIndentType::Hanging) |
3445 | list->append(cssValuePool.createIdentifierValue(CSSValueWebkitHanging)); |
3446 | return list; |
3447 | } |
3448 | #endif |
3449 | return textIndent; |
3450 | } |
3451 | case CSSPropertyTextShadow: |
3452 | return valueForShadow(style.textShadow(), propertyID, style); |
3453 | case CSSPropertyTextRendering: |
3454 | return cssValuePool.createValue(style.fontDescription().textRenderingMode()); |
3455 | case CSSPropertyTextOverflow: |
3456 | if (style.textOverflow() == TextOverflow::Ellipsis) |
3457 | return cssValuePool.createIdentifierValue(CSSValueEllipsis); |
3458 | return cssValuePool.createIdentifierValue(CSSValueClip); |
3459 | case CSSPropertyWebkitTextSecurity: |
3460 | return cssValuePool.createValue(style.textSecurity()); |
3461 | #if ENABLE(TEXT_AUTOSIZING) |
3462 | case CSSPropertyWebkitTextSizeAdjust: |
3463 | if (style.textSizeAdjust().isAuto()) |
3464 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3465 | if (style.textSizeAdjust().isNone()) |
3466 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3467 | return CSSPrimitiveValue::create(style.textSizeAdjust().percentage(), CSSPrimitiveValue::CSS_PERCENTAGE); |
3468 | #endif |
3469 | case CSSPropertyWebkitTextStrokeColor: |
3470 | return currentColorOrValidColor(&style, style.textStrokeColor()); |
3471 | case CSSPropertyWebkitTextStrokeWidth: |
3472 | return zoomAdjustedPixelValue(style.textStrokeWidth(), style); |
3473 | case CSSPropertyTextTransform: |
3474 | return cssValuePool.createValue(style.textTransform()); |
3475 | case CSSPropertyTop: |
3476 | return positionOffsetValue(style, CSSPropertyTop, renderer); |
3477 | case CSSPropertyUnicodeBidi: |
3478 | return cssValuePool.createValue(style.unicodeBidi()); |
3479 | case CSSPropertyVerticalAlign: |
3480 | switch (style.verticalAlign()) { |
3481 | case VerticalAlign::Baseline: |
3482 | return cssValuePool.createIdentifierValue(CSSValueBaseline); |
3483 | case VerticalAlign::Middle: |
3484 | return cssValuePool.createIdentifierValue(CSSValueMiddle); |
3485 | case VerticalAlign::Sub: |
3486 | return cssValuePool.createIdentifierValue(CSSValueSub); |
3487 | case VerticalAlign::Super: |
3488 | return cssValuePool.createIdentifierValue(CSSValueSuper); |
3489 | case VerticalAlign::TextTop: |
3490 | return cssValuePool.createIdentifierValue(CSSValueTextTop); |
3491 | case VerticalAlign::TextBottom: |
3492 | return cssValuePool.createIdentifierValue(CSSValueTextBottom); |
3493 | case VerticalAlign::Top: |
3494 | return cssValuePool.createIdentifierValue(CSSValueTop); |
3495 | case VerticalAlign::Bottom: |
3496 | return cssValuePool.createIdentifierValue(CSSValueBottom); |
3497 | case VerticalAlign::BaselineMiddle: |
3498 | return cssValuePool.createIdentifierValue(CSSValueWebkitBaselineMiddle); |
3499 | case VerticalAlign::Length: |
3500 | return cssValuePool.createValue(style.verticalAlignLength()); |
3501 | } |
3502 | ASSERT_NOT_REACHED(); |
3503 | return nullptr; |
3504 | case CSSPropertyVisibility: |
3505 | return cssValuePool.createValue(style.visibility()); |
3506 | case CSSPropertyWhiteSpace: |
3507 | return cssValuePool.createValue(style.whiteSpace()); |
3508 | case CSSPropertyWidows: |
3509 | if (style.hasAutoWidows()) |
3510 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3511 | return cssValuePool.createValue(style.widows(), CSSPrimitiveValue::CSS_NUMBER); |
3512 | case CSSPropertyWidth: |
3513 | if (renderer && !renderer->isRenderSVGModelObject()) { |
3514 | // According to http://www.w3.org/TR/CSS2/visudet.html#the-width-property, |
3515 | // the "width" property does not apply for non-replaced inline elements. |
3516 | if (isNonReplacedInline(*renderer)) |
3517 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3518 | return zoomAdjustedPixelValue(sizingBox(*renderer).width(), style); |
3519 | } |
3520 | return zoomAdjustedPixelValueForLength(style.width(), style); |
3521 | case CSSPropertyWillChange: |
3522 | return willChangePropertyValue(style.willChange()); |
3523 | case CSSPropertyWordBreak: |
3524 | return cssValuePool.createValue(style.wordBreak()); |
3525 | case CSSPropertyWordSpacing: |
3526 | return zoomAdjustedPixelValue(style.fontCascade().wordSpacing(), style); |
3527 | case CSSPropertyWordWrap: |
3528 | return cssValuePool.createValue(style.overflowWrap()); |
3529 | case CSSPropertyLineBreak: |
3530 | return cssValuePool.createValue(style.lineBreak()); |
3531 | case CSSPropertyWebkitNbspMode: |
3532 | return cssValuePool.createValue(style.nbspMode()); |
3533 | case CSSPropertyResize: |
3534 | return cssValuePool.createValue(style.resize()); |
3535 | case CSSPropertyWebkitFontKerning: |
3536 | return cssValuePool.createValue(style.fontDescription().kerning()); |
3537 | case CSSPropertyWebkitFontSmoothing: |
3538 | return cssValuePool.createValue(style.fontDescription().fontSmoothing()); |
3539 | case CSSPropertyFontVariantLigatures: |
3540 | return fontVariantLigaturesPropertyValue(style.fontDescription().variantCommonLigatures(), style.fontDescription().variantDiscretionaryLigatures(), style.fontDescription().variantHistoricalLigatures(), style.fontDescription().variantContextualAlternates()); |
3541 | case CSSPropertyFontVariantPosition: |
3542 | return fontVariantPositionPropertyValue(style.fontDescription().variantPosition()); |
3543 | case CSSPropertyFontVariantCaps: |
3544 | return fontVariantCapsPropertyValue(style.fontDescription().variantCaps()); |
3545 | case CSSPropertyFontVariantNumeric: |
3546 | return fontVariantNumericPropertyValue(style.fontDescription().variantNumericFigure(), style.fontDescription().variantNumericSpacing(), style.fontDescription().variantNumericFraction(), style.fontDescription().variantNumericOrdinal(), style.fontDescription().variantNumericSlashedZero()); |
3547 | case CSSPropertyFontVariantAlternates: |
3548 | return fontVariantAlternatesPropertyValue(style.fontDescription().variantAlternates()); |
3549 | case CSSPropertyFontVariantEastAsian: |
3550 | return fontVariantEastAsianPropertyValue(style.fontDescription().variantEastAsianVariant(), style.fontDescription().variantEastAsianWidth(), style.fontDescription().variantEastAsianRuby()); |
3551 | case CSSPropertyZIndex: |
3552 | if (style.hasAutoZIndex()) |
3553 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3554 | return cssValuePool.createValue(style.zIndex(), CSSPrimitiveValue::CSS_NUMBER); |
3555 | case CSSPropertyZoom: |
3556 | return cssValuePool.createValue(style.zoom(), CSSPrimitiveValue::CSS_NUMBER); |
3557 | case CSSPropertyBoxSizing: |
3558 | if (style.boxSizing() == BoxSizing::ContentBox) |
3559 | return cssValuePool.createIdentifierValue(CSSValueContentBox); |
3560 | return cssValuePool.createIdentifierValue(CSSValueBorderBox); |
3561 | #if ENABLE(DASHBOARD_SUPPORT) |
3562 | case CSSPropertyWebkitDashboardRegion: |
3563 | { |
3564 | const Vector<StyleDashboardRegion>& regions = style.dashboardRegions(); |
3565 | unsigned count = regions.size(); |
3566 | if (count == 1 && regions[0].type == StyleDashboardRegion::None) |
3567 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3568 | |
3569 | RefPtr<DashboardRegion> firstRegion; |
3570 | DashboardRegion* previousRegion = nullptr; |
3571 | for (unsigned i = 0; i < count; i++) { |
3572 | auto region = DashboardRegion::create(); |
3573 | StyleDashboardRegion styleRegion = regions[i]; |
3574 | |
3575 | region->m_label = styleRegion.label; |
3576 | LengthBox offset = styleRegion.offset; |
3577 | region->setTop(zoomAdjustedPixelValue(offset.top().value(), style)); |
3578 | region->setRight(zoomAdjustedPixelValue(offset.right().value(), style)); |
3579 | region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style)); |
3580 | region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style)); |
3581 | region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle); |
3582 | region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle); |
3583 | |
3584 | if (previousRegion) |
3585 | previousRegion->m_next = region.copyRef(); |
3586 | else |
3587 | firstRegion = region.copyRef(); |
3588 | previousRegion = region.ptr(); |
3589 | } |
3590 | return cssValuePool.createValue(WTFMove(firstRegion)); |
3591 | } |
3592 | #endif |
3593 | case CSSPropertyAnimationDelay: |
3594 | return delayValue(style.animations()); |
3595 | case CSSPropertyAnimationDirection: { |
3596 | auto list = CSSValueList::createCommaSeparated(); |
3597 | const AnimationList* t = style.animations(); |
3598 | if (t) { |
3599 | for (size_t i = 0; i < t->size(); ++i) { |
3600 | switch (t->animation(i).direction()) { |
3601 | case Animation::AnimationDirectionNormal: |
3602 | list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
3603 | break; |
3604 | case Animation::AnimationDirectionAlternate: |
3605 | list->append(cssValuePool.createIdentifierValue(CSSValueAlternate)); |
3606 | break; |
3607 | case Animation::AnimationDirectionReverse: |
3608 | list->append(cssValuePool.createIdentifierValue(CSSValueReverse)); |
3609 | break; |
3610 | case Animation::AnimationDirectionAlternateReverse: |
3611 | list->append(cssValuePool.createIdentifierValue(CSSValueAlternateReverse)); |
3612 | break; |
3613 | } |
3614 | } |
3615 | } else |
3616 | list->append(cssValuePool.createIdentifierValue(CSSValueNormal)); |
3617 | return list; |
3618 | } |
3619 | case CSSPropertyAnimationDuration: |
3620 | return durationValue(style.animations()); |
3621 | case CSSPropertyAnimationFillMode: { |
3622 | auto list = CSSValueList::createCommaSeparated(); |
3623 | const AnimationList* t = style.animations(); |
3624 | if (t) { |
3625 | for (size_t i = 0; i < t->size(); ++i) { |
3626 | switch (t->animation(i).fillMode()) { |
3627 | case AnimationFillMode::None: |
3628 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3629 | break; |
3630 | case AnimationFillMode::Forwards: |
3631 | list->append(cssValuePool.createIdentifierValue(CSSValueForwards)); |
3632 | break; |
3633 | case AnimationFillMode::Backwards: |
3634 | list->append(cssValuePool.createIdentifierValue(CSSValueBackwards)); |
3635 | break; |
3636 | case AnimationFillMode::Both: |
3637 | list->append(cssValuePool.createIdentifierValue(CSSValueBoth)); |
3638 | break; |
3639 | } |
3640 | } |
3641 | } else |
3642 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3643 | return list; |
3644 | } |
3645 | case CSSPropertyAnimationIterationCount: { |
3646 | auto list = CSSValueList::createCommaSeparated(); |
3647 | const AnimationList* t = style.animations(); |
3648 | if (t) { |
3649 | for (size_t i = 0; i < t->size(); ++i) { |
3650 | double iterationCount = t->animation(i).iterationCount(); |
3651 | if (iterationCount == Animation::IterationCountInfinite) |
3652 | list->append(cssValuePool.createIdentifierValue(CSSValueInfinite)); |
3653 | else |
3654 | list->append(cssValuePool.createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER)); |
3655 | } |
3656 | } else |
3657 | list->append(cssValuePool.createValue(Animation::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER)); |
3658 | return list; |
3659 | } |
3660 | case CSSPropertyAnimationName: { |
3661 | auto list = CSSValueList::createCommaSeparated(); |
3662 | const AnimationList* t = style.animations(); |
3663 | if (t) { |
3664 | for (size_t i = 0; i < t->size(); ++i) |
3665 | list->append(cssValuePool.createValue(t->animation(i).name(), CSSPrimitiveValue::CSS_STRING)); |
3666 | } else |
3667 | list->append(cssValuePool.createIdentifierValue(CSSValueNone)); |
3668 | return list; |
3669 | } |
3670 | case CSSPropertyAnimationPlayState: { |
3671 | auto list = CSSValueList::createCommaSeparated(); |
3672 | const AnimationList* t = style.animations(); |
3673 | if (t) { |
3674 | for (size_t i = 0; i < t->size(); ++i) { |
3675 | switch (t->animation(i).playState()) { |
3676 | case AnimationPlayState::Playing: |
3677 | list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); |
3678 | break; |
3679 | case AnimationPlayState::Paused: |
3680 | list->append(cssValuePool.createIdentifierValue(CSSValuePaused)); |
3681 | break; |
3682 | } |
3683 | } |
3684 | } else |
3685 | list->append(cssValuePool.createIdentifierValue(CSSValueRunning)); |
3686 | return list; |
3687 | } |
3688 | case CSSPropertyAnimationTimingFunction: |
3689 | return timingFunctionValue(style.animations()); |
3690 | case CSSPropertyWebkitAppearance: |
3691 | return cssValuePool.createValue(style.appearance()); |
3692 | case CSSPropertyWebkitAspectRatio: |
3693 | switch (style.aspectRatioType()) { |
3694 | case AspectRatioType::Auto: |
3695 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3696 | case AspectRatioType::FromDimensions: |
3697 | return cssValuePool.createIdentifierValue(CSSValueFromDimensions); |
3698 | case AspectRatioType::FromIntrinsic: |
3699 | return cssValuePool.createIdentifierValue(CSSValueFromIntrinsic); |
3700 | case AspectRatioType::Specified: |
3701 | return CSSAspectRatioValue::create(style.aspectRatioNumerator(), style.aspectRatioDenominator()); |
3702 | } |
3703 | ASSERT_NOT_REACHED(); |
3704 | return nullptr; |
3705 | case CSSPropertyWebkitBackfaceVisibility: |
3706 | return cssValuePool.createIdentifierValue((style.backfaceVisibility() == BackfaceVisibility::Hidden) ? CSSValueHidden : CSSValueVisible); |
3707 | case CSSPropertyWebkitBorderImage: |
3708 | return valueForNinePieceImage(style.borderImage()); |
3709 | case CSSPropertyBorderImageOutset: |
3710 | return valueForNinePieceImageQuad(style.borderImage().outset()); |
3711 | case CSSPropertyBorderImageRepeat: |
3712 | return valueForNinePieceImageRepeat(style.borderImage()); |
3713 | case CSSPropertyBorderImageSlice: |
3714 | return valueForNinePieceImageSlice(style.borderImage()); |
3715 | case CSSPropertyBorderImageWidth: |
3716 | return valueForNinePieceImageQuad(style.borderImage().borderSlices()); |
3717 | case CSSPropertyWebkitMaskBoxImage: |
3718 | return valueForNinePieceImage(style.maskBoxImage()); |
3719 | case CSSPropertyWebkitMaskBoxImageOutset: |
3720 | return valueForNinePieceImageQuad(style.maskBoxImage().outset()); |
3721 | case CSSPropertyWebkitMaskBoxImageRepeat: |
3722 | return valueForNinePieceImageRepeat(style.maskBoxImage()); |
3723 | case CSSPropertyWebkitMaskBoxImageSlice: |
3724 | return valueForNinePieceImageSlice(style.maskBoxImage()); |
3725 | case CSSPropertyWebkitMaskBoxImageWidth: |
3726 | return valueForNinePieceImageQuad(style.maskBoxImage().borderSlices()); |
3727 | case CSSPropertyWebkitMaskBoxImageSource: |
3728 | if (style.maskBoxImageSource()) |
3729 | return style.maskBoxImageSource()->cssValue(); |
3730 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3731 | case CSSPropertyWebkitFontSizeDelta: |
3732 | // Not a real style property -- used by the editing engine -- so has no computed value. |
3733 | break; |
3734 | case CSSPropertyWebkitInitialLetter: { |
3735 | auto drop = !style.initialLetterDrop() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterDrop(), CSSPrimitiveValue::CSS_NUMBER); |
3736 | auto size = !style.initialLetterHeight() ? cssValuePool.createIdentifierValue(CSSValueNormal) : cssValuePool.createValue(style.initialLetterHeight(), CSSPrimitiveValue::CSS_NUMBER); |
3737 | return cssValuePool.createValue(Pair::create(WTFMove(drop), WTFMove(size))); |
3738 | } |
3739 | case CSSPropertyWebkitMarginBottomCollapse: |
3740 | case CSSPropertyWebkitMarginAfterCollapse: |
3741 | return cssValuePool.createValue(style.marginAfterCollapse()); |
3742 | case CSSPropertyWebkitMarginTopCollapse: |
3743 | case CSSPropertyWebkitMarginBeforeCollapse: |
3744 | return cssValuePool.createValue(style.marginBeforeCollapse()); |
3745 | #if ENABLE(OVERFLOW_SCROLLING_TOUCH) |
3746 | case CSSPropertyWebkitOverflowScrolling: |
3747 | if (!style.useTouchOverflowScrolling()) |
3748 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3749 | return cssValuePool.createIdentifierValue(CSSValueTouch); |
3750 | #endif |
3751 | case CSSPropertyPerspective: |
3752 | if (!style.hasPerspective()) |
3753 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3754 | return zoomAdjustedPixelValue(style.perspective(), style); |
3755 | case CSSPropertyPerspectiveOrigin: { |
3756 | auto list = CSSValueList::createSpaceSeparated(); |
3757 | if (renderer) { |
3758 | LayoutRect box; |
3759 | if (is<RenderBox>(*renderer)) |
3760 | box = downcast<RenderBox>(*renderer).borderBoxRect(); |
3761 | |
3762 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginX(), box.width()), style)); |
3763 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.perspectiveOriginY(), box.height()), style)); |
3764 | } else { |
3765 | list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginX(), style)); |
3766 | list->append(zoomAdjustedPixelValueForLength(style.perspectiveOriginY(), style)); |
3767 | } |
3768 | return list; |
3769 | } |
3770 | case CSSPropertyWebkitRtlOrdering: |
3771 | return cssValuePool.createIdentifierValue(style.rtlOrdering() == Order::Visual ? CSSValueVisual : CSSValueLogical); |
3772 | #if ENABLE(TOUCH_EVENTS) |
3773 | case CSSPropertyWebkitTapHighlightColor: |
3774 | return currentColorOrValidColor(&style, style.tapHighlightColor()); |
3775 | #endif |
3776 | #if ENABLE(POINTER_EVENTS) |
3777 | case CSSPropertyTouchAction: |
3778 | return touchActionFlagsToCSSValue(style.touchActions()); |
3779 | #endif |
3780 | #if PLATFORM(IOS_FAMILY) |
3781 | case CSSPropertyWebkitTouchCallout: |
3782 | return cssValuePool.createIdentifierValue(style.touchCalloutEnabled() ? CSSValueDefault : CSSValueNone); |
3783 | #endif |
3784 | case CSSPropertyWebkitUserDrag: |
3785 | return cssValuePool.createValue(style.userDrag()); |
3786 | case CSSPropertyWebkitUserSelect: |
3787 | return cssValuePool.createValue(style.userSelect()); |
3788 | case CSSPropertyBorderBottomLeftRadius: |
3789 | return borderRadiusCornerValue(style.borderBottomLeftRadius(), style); |
3790 | case CSSPropertyBorderBottomRightRadius: |
3791 | return borderRadiusCornerValue(style.borderBottomRightRadius(), style); |
3792 | case CSSPropertyBorderTopLeftRadius: |
3793 | return borderRadiusCornerValue(style.borderTopLeftRadius(), style); |
3794 | case CSSPropertyBorderTopRightRadius: |
3795 | return borderRadiusCornerValue(style.borderTopRightRadius(), style); |
3796 | case CSSPropertyClip: { |
3797 | if (!style.hasClip()) |
3798 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
3799 | auto rect = Rect::create(); |
3800 | rect->setTop(autoOrZoomAdjustedValue(style.clip().top(), style)); |
3801 | rect->setRight(autoOrZoomAdjustedValue(style.clip().right(), style)); |
3802 | rect->setBottom(autoOrZoomAdjustedValue(style.clip().bottom(), style)); |
3803 | rect->setLeft(autoOrZoomAdjustedValue(style.clip().left(), style)); |
3804 | return cssValuePool.createValue(WTFMove(rect)); |
3805 | } |
3806 | case CSSPropertySpeakAs: |
3807 | return speakAsToCSSValue(style.speakAs()); |
3808 | case CSSPropertyTransform: |
3809 | return computedTransform(renderer, style); |
3810 | case CSSPropertyTransformBox: |
3811 | return CSSPrimitiveValue::create(style.transformBox()); |
3812 | case CSSPropertyTransformOrigin: { |
3813 | auto list = CSSValueList::createSpaceSeparated(); |
3814 | if (renderer) { |
3815 | LayoutRect box; |
3816 | if (is<RenderBox>(*renderer)) |
3817 | box = downcast<RenderBox>(*renderer).borderBoxRect(); |
3818 | |
3819 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginX(), box.width()), style)); |
3820 | list->append(zoomAdjustedPixelValue(minimumValueForLength(style.transformOriginY(), box.height()), style)); |
3821 | if (style.transformOriginZ()) |
3822 | list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style)); |
3823 | } else { |
3824 | list->append(zoomAdjustedPixelValueForLength(style.transformOriginX(), style)); |
3825 | list->append(zoomAdjustedPixelValueForLength(style.transformOriginY(), style)); |
3826 | if (style.transformOriginZ()) |
3827 | list->append(zoomAdjustedPixelValue(style.transformOriginZ(), style)); |
3828 | } |
3829 | return list; |
3830 | } |
3831 | case CSSPropertyTransformStyle: |
3832 | case CSSPropertyWebkitTransformStyle: |
3833 | return cssValuePool.createIdentifierValue((style.transformStyle3D() == TransformStyle3D::Preserve3D) ? CSSValuePreserve3d : CSSValueFlat); |
3834 | case CSSPropertyTransitionDelay: |
3835 | return delayValue(style.transitions()); |
3836 | case CSSPropertyTransitionDuration: |
3837 | return durationValue(style.transitions()); |
3838 | case CSSPropertyTransitionProperty: |
3839 | return transitionPropertyValue(style.transitions()); |
3840 | case CSSPropertyTransitionTimingFunction: |
3841 | return timingFunctionValue(style.transitions()); |
3842 | case CSSPropertyTransition: { |
3843 | if (auto* animationList = style.transitions()) { |
3844 | auto transitionsList = CSSValueList::createCommaSeparated(); |
3845 | for (size_t i = 0; i < animationList->size(); ++i) { |
3846 | auto list = CSSValueList::createSpaceSeparated(); |
3847 | auto& animation = animationList->animation(i); |
3848 | list->append(createTransitionPropertyValue(animation)); |
3849 | list->append(cssValuePool.createValue(animation.duration(), CSSPrimitiveValue::CSS_S)); |
3850 | list->append(createTimingFunctionValue(*animation.timingFunction())); |
3851 | list->append(cssValuePool.createValue(animation.delay(), CSSPrimitiveValue::CSS_S)); |
3852 | transitionsList->append(WTFMove(list)); |
3853 | } |
3854 | return transitionsList; |
3855 | } |
3856 | |
3857 | auto list = CSSValueList::createSpaceSeparated(); |
3858 | // transition-property default value. |
3859 | list->append(cssValuePool.createIdentifierValue(CSSValueAll)); |
3860 | list->append(cssValuePool.createValue(Animation::initialDuration(), CSSPrimitiveValue::CSS_S)); |
3861 | list->append(createTimingFunctionValue(Animation::initialTimingFunction())); |
3862 | list->append(cssValuePool.createValue(Animation::initialDelay(), CSSPrimitiveValue::CSS_S)); |
3863 | return list; |
3864 | } |
3865 | case CSSPropertyPointerEvents: |
3866 | return cssValuePool.createValue(style.pointerEvents()); |
3867 | case CSSPropertyWebkitLineGrid: |
3868 | if (style.lineGrid().isNull()) |
3869 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3870 | return cssValuePool.createValue(style.lineGrid(), CSSPrimitiveValue::CSS_STRING); |
3871 | case CSSPropertyWebkitLineSnap: |
3872 | return CSSPrimitiveValue::create(style.lineSnap()); |
3873 | case CSSPropertyWebkitLineAlign: |
3874 | return CSSPrimitiveValue::create(style.lineAlign()); |
3875 | case CSSPropertyWritingMode: |
3876 | return cssValuePool.createValue(style.writingMode()); |
3877 | case CSSPropertyWebkitTextCombine: |
3878 | return cssValuePool.createValue(style.textCombine()); |
3879 | case CSSPropertyWebkitTextOrientation: |
3880 | return CSSPrimitiveValue::create(style.textOrientation()); |
3881 | case CSSPropertyWebkitLineBoxContain: |
3882 | return createLineBoxContainValue(style.lineBoxContain()); |
3883 | case CSSPropertyAlt: |
3884 | return altTextToCSSValue(style); |
3885 | case CSSPropertyContent: |
3886 | return contentToCSSValue(style); |
3887 | case CSSPropertyCounterIncrement: |
3888 | return counterToCSSValue(style, propertyID); |
3889 | case CSSPropertyCounterReset: |
3890 | return counterToCSSValue(style, propertyID); |
3891 | case CSSPropertyWebkitClipPath: { |
3892 | auto* operation = style.clipPath(); |
3893 | if (!operation) |
3894 | return cssValuePool.createIdentifierValue(CSSValueNone); |
3895 | if (is<ReferenceClipPathOperation>(*operation)) |
3896 | return CSSPrimitiveValue::create(downcast<ReferenceClipPathOperation>(*operation).url(), CSSPrimitiveValue::CSS_URI); |
3897 | auto list = CSSValueList::createSpaceSeparated(); |
3898 | if (is<ShapeClipPathOperation>(*operation)) { |
3899 | auto& shapeOperation = downcast<ShapeClipPathOperation>(*operation); |
3900 | list->append(valueForBasicShape(style, shapeOperation.basicShape())); |
3901 | if (shapeOperation.referenceBox() != CSSBoxType::BoxMissing) |
3902 | list->append(cssValuePool.createValue(shapeOperation.referenceBox())); |
3903 | } |
3904 | if (is<BoxClipPathOperation>(*operation)) |
3905 | list->append(cssValuePool.createValue(downcast<BoxClipPathOperation>(*operation).referenceBox())); |
3906 | return list; |
3907 | } |
3908 | case CSSPropertyShapeMargin: |
3909 | return cssValuePool.createValue(style.shapeMargin(), style); |
3910 | case CSSPropertyShapeImageThreshold: |
3911 | return cssValuePool.createValue(style.shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER); |
3912 | case CSSPropertyShapeOutside: |
3913 | return shapePropertyValue(style, style.shapeOutside()); |
3914 | case CSSPropertyFilter: |
3915 | return valueForFilter(style, style.filter()); |
3916 | case CSSPropertyAppleColorFilter: |
3917 | return valueForFilter(style, style.appleColorFilter()); |
3918 | #if ENABLE(FILTERS_LEVEL_2) |
3919 | case CSSPropertyWebkitBackdropFilter: |
3920 | return valueForFilter(style, style.backdropFilter()); |
3921 | #endif |
3922 | #if ENABLE(CSS_COMPOSITING) |
3923 | case CSSPropertyMixBlendMode: |
3924 | return cssValuePool.createValue(style.blendMode()); |
3925 | case CSSPropertyIsolation: |
3926 | return cssValuePool.createValue(style.isolation()); |
3927 | #endif |
3928 | case CSSPropertyBackgroundBlendMode: { |
3929 | auto& layers = style.backgroundLayers(); |
3930 | if (!layers.next()) |
3931 | return cssValuePool.createValue(layers.blendMode()); |
3932 | auto list = CSSValueList::createCommaSeparated(); |
3933 | for (auto* currLayer = &layers; currLayer; currLayer = currLayer->next()) |
3934 | list->append(cssValuePool.createValue(currLayer->blendMode())); |
3935 | return list; |
3936 | } |
3937 | case CSSPropertyBackground: |
3938 | return getBackgroundShorthandValue(); |
3939 | case CSSPropertyBorder: { |
3940 | auto value = propertyValue(CSSPropertyBorderTop, DoNotUpdateLayout); |
3941 | const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft }; |
3942 | for (auto& property : properties) { |
3943 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(property, DoNotUpdateLayout))) |
3944 | return nullptr; |
3945 | } |
3946 | return value; |
3947 | } |
3948 | case CSSPropertyBorderBlock: { |
3949 | auto value = propertyValue(CSSPropertyBorderBlockStart, DoNotUpdateLayout); |
3950 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderBlockEnd, DoNotUpdateLayout))) |
3951 | return nullptr; |
3952 | return value; |
3953 | } |
3954 | case CSSPropertyBorderBlockColor: |
3955 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockColorShorthand()); |
3956 | case CSSPropertyBorderBlockStyle: |
3957 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockStyleShorthand()); |
3958 | case CSSPropertyBorderBlockWidth: |
3959 | return getCSSPropertyValuesFor2SidesShorthand(borderBlockWidthShorthand()); |
3960 | case CSSPropertyBorderBottom: |
3961 | return getCSSPropertyValuesForShorthandProperties(borderBottomShorthand()); |
3962 | case CSSPropertyBorderColor: |
3963 | return getCSSPropertyValuesFor4SidesShorthand(borderColorShorthand()); |
3964 | case CSSPropertyBorderLeft: |
3965 | return getCSSPropertyValuesForShorthandProperties(borderLeftShorthand()); |
3966 | case CSSPropertyBorderImage: |
3967 | return valueForNinePieceImage(style.borderImage()); |
3968 | case CSSPropertyBorderInline: { |
3969 | auto value = propertyValue(CSSPropertyBorderInlineStart, DoNotUpdateLayout); |
3970 | if (!compareCSSValuePtr<CSSValue>(value, propertyValue(CSSPropertyBorderInlineEnd, DoNotUpdateLayout))) |
3971 | return nullptr; |
3972 | return value; |
3973 | } |
3974 | case CSSPropertyBorderInlineColor: |
3975 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineColorShorthand()); |
3976 | case CSSPropertyBorderInlineStyle: |
3977 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineStyleShorthand()); |
3978 | case CSSPropertyBorderInlineWidth: |
3979 | return getCSSPropertyValuesFor2SidesShorthand(borderInlineWidthShorthand()); |
3980 | case CSSPropertyBorderRadius: |
3981 | return borderRadiusShorthandValue(style); |
3982 | case CSSPropertyBorderRight: |
3983 | return getCSSPropertyValuesForShorthandProperties(borderRightShorthand()); |
3984 | case CSSPropertyBorderStyle: |
3985 | return getCSSPropertyValuesFor4SidesShorthand(borderStyleShorthand()); |
3986 | case CSSPropertyBorderTop: |
3987 | return getCSSPropertyValuesForShorthandProperties(borderTopShorthand()); |
3988 | case CSSPropertyBorderWidth: |
3989 | return getCSSPropertyValuesFor4SidesShorthand(borderWidthShorthand()); |
3990 | case CSSPropertyColumnRule: |
3991 | return getCSSPropertyValuesForShorthandProperties(columnRuleShorthand()); |
3992 | case CSSPropertyColumns: |
3993 | return getCSSPropertyValuesForShorthandProperties(columnsShorthand()); |
3994 | case CSSPropertyInset: |
3995 | return getCSSPropertyValuesFor4SidesShorthand(insetShorthand()); |
3996 | case CSSPropertyInsetBlock: |
3997 | return getCSSPropertyValuesFor2SidesShorthand(insetBlockShorthand()); |
3998 | case CSSPropertyInsetInline: |
3999 | return getCSSPropertyValuesFor2SidesShorthand(insetInlineShorthand()); |
4000 | case CSSPropertyListStyle: |
4001 | return getCSSPropertyValuesForShorthandProperties(listStyleShorthand()); |
4002 | case CSSPropertyMargin: |
4003 | return getCSSPropertyValuesFor4SidesShorthand(marginShorthand()); |
4004 | case CSSPropertyMarginBlock: |
4005 | return getCSSPropertyValuesFor2SidesShorthand(marginBlockShorthand()); |
4006 | case CSSPropertyMarginInline: |
4007 | return getCSSPropertyValuesFor2SidesShorthand(marginInlineShorthand()); |
4008 | case CSSPropertyOutline: |
4009 | return getCSSPropertyValuesForShorthandProperties(outlineShorthand()); |
4010 | case CSSPropertyPadding: |
4011 | return getCSSPropertyValuesFor4SidesShorthand(paddingShorthand()); |
4012 | case CSSPropertyPaddingBlock: |
4013 | return getCSSPropertyValuesFor2SidesShorthand(paddingBlockShorthand()); |
4014 | case CSSPropertyPaddingInline: |
4015 | return getCSSPropertyValuesFor2SidesShorthand(paddingInlineShorthand()); |
4016 | #if ENABLE(CSS_SCROLL_SNAP) |
4017 | case CSSPropertyScrollSnapMargin: |
4018 | return getCSSPropertyValuesFor4SidesShorthand(scrollSnapMarginShorthand()); |
4019 | case CSSPropertyScrollSnapMarginBottom: |
4020 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginBottom(), style); |
4021 | case CSSPropertyScrollSnapMarginTop: |
4022 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginTop(), style); |
4023 | case CSSPropertyScrollSnapMarginRight: |
4024 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginRight(), style); |
4025 | case CSSPropertyScrollSnapMarginLeft: |
4026 | return zoomAdjustedPixelValueForLength(style.scrollSnapMarginLeft(), style); |
4027 | case CSSPropertyScrollPadding: |
4028 | return getCSSPropertyValuesFor4SidesShorthand(scrollPaddingShorthand()); |
4029 | case CSSPropertyScrollPaddingBottom: |
4030 | return zoomAdjustedPixelValueForLength(style.scrollPaddingBottom(), style); |
4031 | case CSSPropertyScrollPaddingTop: |
4032 | return zoomAdjustedPixelValueForLength(style.scrollPaddingTop(), style); |
4033 | case CSSPropertyScrollPaddingRight: |
4034 | return zoomAdjustedPixelValueForLength(style.scrollPaddingRight(), style); |
4035 | case CSSPropertyScrollPaddingLeft: |
4036 | return zoomAdjustedPixelValueForLength(style.scrollPaddingLeft(), style); |
4037 | case CSSPropertyScrollSnapType: |
4038 | return valueForScrollSnapType(style.scrollSnapType()); |
4039 | case CSSPropertyScrollSnapAlign: |
4040 | return valueForScrollSnapAlignment(style.scrollSnapAlign()); |
4041 | #endif |
4042 | |
4043 | #if ENABLE(CSS_TRAILING_WORD) |
4044 | case CSSPropertyAppleTrailingWord: |
4045 | return cssValuePool.createValue(style.trailingWord()); |
4046 | #endif |
4047 | |
4048 | #if ENABLE(APPLE_PAY) |
4049 | case CSSPropertyApplePayButtonStyle: |
4050 | return cssValuePool.createValue(style.applePayButtonStyle()); |
4051 | case CSSPropertyApplePayButtonType: |
4052 | return cssValuePool.createValue(style.applePayButtonType()); |
4053 | #endif |
4054 | |
4055 | #if ENABLE(DARK_MODE_CSS) |
4056 | case CSSPropertyColorScheme: { |
4057 | if (!RuntimeEnabledFeatures::sharedFeatures().darkModeCSSEnabled()) |
4058 | return nullptr; |
4059 | |
4060 | auto colorScheme = style.colorScheme(); |
4061 | if (colorScheme.isAuto()) |
4062 | return cssValuePool.createIdentifierValue(CSSValueAuto); |
4063 | |
4064 | auto list = CSSValueList::createSpaceSeparated(); |
4065 | if (colorScheme.contains(ColorScheme::Light)) |
4066 | list->append(cssValuePool.createIdentifierValue(CSSValueLight)); |
4067 | if (colorScheme.contains(ColorScheme::Dark)) |
4068 | list->append(cssValuePool.createIdentifierValue(CSSValueDark)); |
4069 | if (!colorScheme.allowsTransformations()) |
4070 | list->append(cssValuePool.createIdentifierValue(CSSValueOnly)); |
4071 | ASSERT(list->length()); |
4072 | return list; |
4073 | } |
4074 | #endif |
4075 | |
4076 | /* Individual properties not part of the spec */ |
4077 | case CSSPropertyBackgroundRepeatX: |
4078 | case CSSPropertyBackgroundRepeatY: |
4079 | break; |
4080 | |
4081 | // Length properties for SVG. |
4082 | case CSSPropertyCx: |
4083 | return zoomAdjustedPixelValueForLength(style.svgStyle().cx(), style); |
4084 | case CSSPropertyCy: |
4085 | return zoomAdjustedPixelValueForLength(style.svgStyle().cy(), style); |
4086 | case CSSPropertyR: |
4087 | return zoomAdjustedPixelValueForLength(style.svgStyle().r(), style); |
4088 | case CSSPropertyRx: |
4089 | return zoomAdjustedPixelValueForLength(style.svgStyle().rx(), style); |
4090 | case CSSPropertyRy: |
4091 | return zoomAdjustedPixelValueForLength(style.svgStyle().ry(), style); |
4092 | case CSSPropertyStrokeDashoffset: |
4093 | return zoomAdjustedPixelValueForLength(style.svgStyle().strokeDashOffset(), style); |
4094 | case CSSPropertyX: |
4095 | return zoomAdjustedPixelValueForLength(style.svgStyle().x(), style); |
4096 | case CSSPropertyY: |
4097 | return zoomAdjustedPixelValueForLength(style.svgStyle().y(), style); |
4098 | case CSSPropertyWebkitTextZoom: |
4099 | return cssValuePool.createValue(style.textZoom()); |
4100 | |
4101 | case CSSPropertyPaintOrder: |
4102 | return paintOrder(style.paintOrder()); |
4103 | case CSSPropertyStrokeLinecap: |
4104 | return CSSPrimitiveValue::create(style.capStyle()); |
4105 | case CSSPropertyStrokeLinejoin: |
4106 | return CSSPrimitiveValue::create(style.joinStyle()); |
4107 | case CSSPropertyStrokeWidth: |
4108 | return zoomAdjustedPixelValueForLength(style.strokeWidth(), style); |
4109 | case CSSPropertyStrokeColor: |
4110 | return currentColorOrValidColor(&style, style.strokeColor()); |
4111 | case CSSPropertyStrokeMiterlimit: |
4112 | return CSSPrimitiveValue::create(style.strokeMiterLimit(), CSSPrimitiveValue::CSS_NUMBER); |
4113 | |
4114 | /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */ |
4115 | case CSSPropertyAll: |
4116 | case CSSPropertyAnimation: |
4117 | case CSSPropertyWebkitTextEmphasis: |
4118 | break; |
4119 | |
4120 | /* Directional properties are resolved by resolveDirectionAwareProperty() before the switch. */ |
4121 | case CSSPropertyBorderBlockEnd: |
4122 | case CSSPropertyBorderBlockEndColor: |
4123 | case CSSPropertyBorderBlockEndStyle: |
4124 | case CSSPropertyBorderBlockEndWidth: |
4125 | case CSSPropertyBorderBlockStart: |
4126 | case CSSPropertyBorderBlockStartColor: |
4127 | case CSSPropertyBorderBlockStartStyle: |
4128 | case CSSPropertyBorderBlockStartWidth: |
4129 | case CSSPropertyBorderInlineEnd: |
4130 | case CSSPropertyBorderInlineEndColor: |
4131 | case CSSPropertyBorderInlineEndStyle: |
4132 | case CSSPropertyBorderInlineEndWidth: |
4133 | case CSSPropertyBorderInlineStart: |
4134 | case CSSPropertyBorderInlineStartColor: |
4135 | case CSSPropertyBorderInlineStartStyle: |
4136 | case CSSPropertyBorderInlineStartWidth: |
4137 | case CSSPropertyInsetBlockEnd: |
4138 | case CSSPropertyInsetBlockStart: |
4139 | case CSSPropertyInsetInlineEnd: |
4140 | case CSSPropertyInsetInlineStart: |
4141 | case CSSPropertyMarginBlockEnd: |
4142 | case CSSPropertyMarginBlockStart: |
4143 | case CSSPropertyMarginInlineEnd: |
4144 | case CSSPropertyMarginInlineStart: |
4145 | case CSSPropertyPaddingBlockEnd: |
4146 | case CSSPropertyPaddingBlockStart: |
4147 | case CSSPropertyPaddingInlineEnd: |
4148 | case CSSPropertyPaddingInlineStart: |
4149 | case CSSPropertyBlockSize: |
4150 | case CSSPropertyInlineSize: |
4151 | case CSSPropertyMaxBlockSize: |
4152 | case CSSPropertyMaxInlineSize: |
4153 | case CSSPropertyMinBlockSize: |
4154 | case CSSPropertyMinInlineSize: |
4155 | ASSERT_NOT_REACHED(); |
4156 | break; |
4157 | |
4158 | /* Unimplemented @font-face properties */ |
4159 | case CSSPropertySrc: |
4160 | case CSSPropertyUnicodeRange: |
4161 | case CSSPropertyFontDisplay: |
4162 | break; |
4163 | |
4164 | /* Other unimplemented properties */ |
4165 | case CSSPropertyPage: // for @page |
4166 | case CSSPropertyQuotes: // FIXME: needs implementation |
4167 | case CSSPropertySize: // for @page |
4168 | break; |
4169 | |
4170 | /* Unimplemented -webkit- properties */ |
4171 | case CSSPropertyWebkitBorderRadius: |
4172 | case CSSPropertyWebkitMarginCollapse: |
4173 | case CSSPropertyWebkitMarquee: |
4174 | case CSSPropertyWebkitMarqueeSpeed: |
4175 | case CSSPropertyWebkitMask: |
4176 | case CSSPropertyWebkitMaskRepeatX: |
4177 | case CSSPropertyWebkitMaskRepeatY: |
4178 | case CSSPropertyPerspectiveOriginX: |
4179 | case CSSPropertyPerspectiveOriginY: |
4180 | case CSSPropertyWebkitTextStroke: |
4181 | case CSSPropertyTransformOriginX: |
4182 | case CSSPropertyTransformOriginY: |
4183 | case CSSPropertyTransformOriginZ: |
4184 | break; |
4185 | |
4186 | #if ENABLE(CSS_DEVICE_ADAPTATION) |
4187 | case CSSPropertyMaxZoom: |
4188 | case CSSPropertyMinZoom: |
4189 | case CSSPropertyOrientation: |
4190 | case CSSPropertyUserZoom: |
4191 | break; |
4192 | #endif |
4193 | |
4194 | case CSSPropertyBufferedRendering: |
4195 | case CSSPropertyClipPath: |
4196 | case CSSPropertyClipRule: |
4197 | case CSSPropertyMask: |
4198 | case CSSPropertyEnableBackground: |
4199 | case CSSPropertyFloodColor: |
4200 | case CSSPropertyFloodOpacity: |
4201 | case CSSPropertyLightingColor: |
4202 | case CSSPropertyStopColor: |
4203 | case CSSPropertyStopOpacity: |
4204 | case CSSPropertyColorInterpolation: |
4205 | case CSSPropertyColorInterpolationFilters: |
4206 | case CSSPropertyColorProfile: |
4207 | case CSSPropertyColorRendering: |
4208 | case CSSPropertyFill: |
4209 | case CSSPropertyFillOpacity: |
4210 | case CSSPropertyFillRule: |
4211 | case CSSPropertyMarker: |
4212 | case CSSPropertyMarkerEnd: |
4213 | case CSSPropertyMarkerMid: |
4214 | case CSSPropertyMarkerStart: |
4215 | case CSSPropertyMaskType: |
4216 | case CSSPropertyShapeRendering: |
4217 | case CSSPropertyStroke: |
4218 | case CSSPropertyStrokeDasharray: |
4219 | case CSSPropertyStrokeOpacity: |
4220 | case CSSPropertyAlignmentBaseline: |
4221 | case CSSPropertyBaselineShift: |
4222 | case CSSPropertyDominantBaseline: |
4223 | case CSSPropertyGlyphOrientationHorizontal: |
4224 | case CSSPropertyGlyphOrientationVertical: |
4225 | case CSSPropertyKerning: |
4226 | case CSSPropertyTextAnchor: |
4227 | case CSSPropertyVectorEffect: |
4228 | return svgPropertyValue(propertyID, DoNotUpdateLayout); |
4229 | case CSSPropertyCustom: |
4230 | ASSERT_NOT_REACHED(); |
4231 | return nullptr; |
4232 | } |
4233 | |
4234 | logUnimplementedPropertyID(propertyID); |
4235 | return nullptr; |
4236 | } |
4237 | |
4238 | String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const |
4239 | { |
4240 | auto value = getPropertyCSSValue(propertyID); |
4241 | if (!value) |
4242 | return emptyString(); // FIXME: Should this be null instead, as it is in StyleProperties::getPropertyValue? |
4243 | return value->cssText(); |
4244 | } |
4245 | |
4246 | unsigned CSSComputedStyleDeclaration::length() const |
4247 | { |
4248 | updateStyleIfNeededForProperty(m_element.get(), CSSPropertyCustom); |
4249 | |
4250 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
4251 | if (!style) |
4252 | return 0; |
4253 | |
4254 | return numComputedProperties + style->inheritedCustomProperties().size() + style->nonInheritedCustomProperties().size(); |
4255 | } |
4256 | |
4257 | String CSSComputedStyleDeclaration::item(unsigned i) const |
4258 | { |
4259 | if (i >= length()) |
4260 | return String(); |
4261 | |
4262 | if (i < numComputedProperties) |
4263 | return getPropertyNameString(computedProperties[i]); |
4264 | |
4265 | auto* style = m_element->computedStyle(m_pseudoElementSpecifier); |
4266 | if (!style) |
4267 | return String(); |
4268 | |
4269 | const auto& inheritedCustomProperties = style->inheritedCustomProperties(); |
4270 | |
4271 | if (i < numComputedProperties + inheritedCustomProperties.size()) { |
4272 | auto results = copyToVector(inheritedCustomProperties.keys()); |
4273 | return results.at(i - numComputedProperties); |
4274 | } |
4275 | |
4276 | const auto& nonInheritedCustomProperties = style->nonInheritedCustomProperties(); |
4277 | auto results = copyToVector(nonInheritedCustomProperties.keys()); |
4278 | return results.at(i - inheritedCustomProperties.size() - numComputedProperties); |
4279 | } |
4280 | |
4281 | bool ComputedStyleExtractor::(CSSPropertyID propertyID, const CSSValue* value) |
4282 | { |
4283 | if (!m_element) |
4284 | return false; |
4285 | if (propertyID == CSSPropertyFontSize && is<CSSPrimitiveValue>(*value)) { |
4286 | m_element->document().updateLayoutIgnorePendingStylesheets(); |
4287 | if (auto* style = m_element->computedStyle(m_pseudoElementSpecifier)) { |
4288 | if (CSSValueID sizeIdentifier = style->fontDescription().keywordSizeAsIdentifier()) { |
4289 | auto& primitiveValue = downcast<CSSPrimitiveValue>(*value); |
4290 | if (primitiveValue.isValueID() && primitiveValue.valueID() == sizeIdentifier) |
4291 | return true; |
4292 | } |
4293 | } |
4294 | } |
4295 | RefPtr<CSSValue> computedValue = propertyValue(propertyID); |
4296 | return computedValue && value && computedValue->equals(*value); |
4297 | } |
4298 | |
4299 | Ref<MutableStyleProperties> ComputedStyleExtractor::() |
4300 | { |
4301 | return copyPropertiesInSet(computedProperties, numComputedProperties); |
4302 | } |
4303 | |
4304 | Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForShorthandProperties(const StylePropertyShorthand& shorthand) |
4305 | { |
4306 | auto list = CSSValueList::createSpaceSeparated(); |
4307 | for (size_t i = 0; i < shorthand.length(); ++i) |
4308 | list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); |
4309 | return list; |
4310 | } |
4311 | |
4312 | RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor2SidesShorthand(const StylePropertyShorthand& shorthand) |
4313 | { |
4314 | auto list = CSSValueList::createSpaceSeparated(); |
4315 | |
4316 | // Assume the properties are in the usual order start, end. |
4317 | auto startValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); |
4318 | auto endValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); |
4319 | |
4320 | // All 2 properties must be specified. |
4321 | if (!startValue || !endValue) |
4322 | return nullptr; |
4323 | |
4324 | bool showEnd = !compareCSSValuePtr(startValue, endValue); |
4325 | |
4326 | list->append(startValue.releaseNonNull()); |
4327 | if (showEnd) |
4328 | list->append(endValue.releaseNonNull()); |
4329 | |
4330 | return list; |
4331 | } |
4332 | |
4333 | RefPtr<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesFor4SidesShorthand(const StylePropertyShorthand& shorthand) |
4334 | { |
4335 | auto list = CSSValueList::createSpaceSeparated(); |
4336 | |
4337 | // Assume the properties are in the usual order top, right, bottom, left. |
4338 | auto topValue = propertyValue(shorthand.properties()[0], DoNotUpdateLayout); |
4339 | auto rightValue = propertyValue(shorthand.properties()[1], DoNotUpdateLayout); |
4340 | auto bottomValue = propertyValue(shorthand.properties()[2], DoNotUpdateLayout); |
4341 | auto leftValue = propertyValue(shorthand.properties()[3], DoNotUpdateLayout); |
4342 | |
4343 | // All 4 properties must be specified. |
4344 | if (!topValue || !rightValue || !bottomValue || !leftValue) |
4345 | return nullptr; |
4346 | |
4347 | bool showLeft = !compareCSSValuePtr(rightValue, leftValue); |
4348 | bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft; |
4349 | bool showRight = !compareCSSValuePtr(topValue, rightValue) || showBottom; |
4350 | |
4351 | list->append(topValue.releaseNonNull()); |
4352 | if (showRight) |
4353 | list->append(rightValue.releaseNonNull()); |
4354 | if (showBottom) |
4355 | list->append(bottomValue.releaseNonNull()); |
4356 | if (showLeft) |
4357 | list->append(leftValue.releaseNonNull()); |
4358 | |
4359 | return list; |
4360 | } |
4361 | |
4362 | Ref<CSSValueList> ComputedStyleExtractor::getCSSPropertyValuesForGridShorthand(const StylePropertyShorthand& shorthand) |
4363 | { |
4364 | auto list = CSSValueList::createSlashSeparated(); |
4365 | for (size_t i = 0; i < shorthand.length(); ++i) |
4366 | list->append(propertyValue(shorthand.properties()[i], DoNotUpdateLayout).releaseNonNull()); |
4367 | return list; |
4368 | } |
4369 | |
4370 | Ref<MutableStyleProperties> ComputedStyleExtractor::(const CSSPropertyID* set, unsigned length) |
4371 | { |
4372 | Vector<CSSProperty, 256> list; |
4373 | list.reserveInitialCapacity(length); |
4374 | for (unsigned i = 0; i < length; ++i) { |
4375 | if (auto value = propertyValue(set[i])) |
4376 | list.append(CSSProperty(set[i], WTFMove(value), false)); |
4377 | } |
4378 | return MutableStyleProperties::create(list.data(), list.size()); |
4379 | } |
4380 | |
4381 | CSSRule* CSSComputedStyleDeclaration::parentRule() const |
4382 | { |
4383 | return nullptr; |
4384 | } |
4385 | |
4386 | RefPtr<DeprecatedCSSOMValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName) |
4387 | { |
4388 | if (isCustomPropertyName(propertyName)) { |
4389 | auto value = ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyValue(propertyName); |
4390 | if (!value) |
4391 | return nullptr; |
4392 | return value->createDeprecatedCSSOMWrapper(*this); |
4393 | } |
4394 | |
4395 | CSSPropertyID propertyID = cssPropertyID(propertyName); |
4396 | if (!propertyID) |
4397 | return nullptr; |
4398 | auto value = getPropertyCSSValue(propertyID); |
4399 | if (!value) |
4400 | return nullptr; |
4401 | return value->createDeprecatedCSSOMWrapper(*this); |
4402 | } |
4403 | |
4404 | String CSSComputedStyleDeclaration::getPropertyValue(const String &propertyName) |
4405 | { |
4406 | if (isCustomPropertyName(propertyName)) |
4407 | return ComputedStyleExtractor(m_element.ptr(), m_allowVisitedStyle, m_pseudoElementSpecifier).customPropertyText(propertyName); |
4408 | |
4409 | CSSPropertyID propertyID = cssPropertyID(propertyName); |
4410 | if (!propertyID) |
4411 | return String(); |
4412 | return getPropertyValue(propertyID); |
4413 | } |
4414 | |
4415 | String CSSComputedStyleDeclaration::getPropertyPriority(const String&) |
4416 | { |
4417 | // All computed styles have a priority of not "important". |
4418 | return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? |
4419 | } |
4420 | |
4421 | String CSSComputedStyleDeclaration::getPropertyShorthand(const String&) |
4422 | { |
4423 | return emptyString(); // FIXME: Should this sometimes be null instead of empty, to match a normal style declaration? |
4424 | } |
4425 | |
4426 | bool CSSComputedStyleDeclaration::isPropertyImplicit(const String&) |
4427 | { |
4428 | return false; |
4429 | } |
4430 | |
4431 | ExceptionOr<void> CSSComputedStyleDeclaration::setProperty(const String&, const String&, const String&) |
4432 | { |
4433 | return Exception { NoModificationAllowedError }; |
4434 | } |
4435 | |
4436 | ExceptionOr<String> CSSComputedStyleDeclaration::removeProperty(const String&) |
4437 | { |
4438 | return Exception { NoModificationAllowedError }; |
4439 | } |
4440 | |
4441 | RefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID) |
4442 | { |
4443 | return getPropertyCSSValue(propertyID); |
4444 | } |
4445 | |
4446 | String CSSComputedStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID) |
4447 | { |
4448 | return getPropertyValue(propertyID); |
4449 | } |
4450 | |
4451 | ExceptionOr<bool> CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID, const String&, bool) |
4452 | { |
4453 | return Exception { NoModificationAllowedError }; |
4454 | } |
4455 | |
4456 | Ref<CSSValueList> ComputedStyleExtractor::getBackgroundShorthandValue() |
4457 | { |
4458 | static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition }; |
4459 | static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin, CSSPropertyBackgroundClip }; |
4460 | |
4461 | auto list = CSSValueList::createSlashSeparated(); |
4462 | list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator))); |
4463 | list->append(getCSSPropertyValuesForShorthandProperties(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator))); |
4464 | return list; |
4465 | } |
4466 | |
4467 | } // namespace WebCore |
4468 | |