[CSS Container Queries] Correct container selection for pseudo-elements
[webkit.git] / Source / WebCore / css / CSSPrimitiveValue.cpp
bloba1f48239ba80bbb410e78da6fa17666d0451af61
1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2012, 2013 Apple Inc. All rights reserved.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "config.h"
22 #include "CSSPrimitiveValue.h"
24 #include "CSSBasicShapes.h"
25 #include "CSSCalcValue.h"
26 #include "CSSFontFamily.h"
27 #include "CSSHelper.h"
28 #include "CSSMarkup.h"
29 #include "CSSParserIdioms.h"
30 #include "CSSPrimitiveValueMappings.h"
31 #include "CSSPropertyNames.h"
32 #include "CSSToLengthConversionData.h"
33 #include "CSSValueKeywords.h"
34 #include "CalculationCategory.h"
35 #include "CalculationValue.h"
36 #include "Color.h"
37 #include "ColorSerialization.h"
38 #include "ContainerQueryEvaluator.h"
39 #include "Counter.h"
40 #include "DeprecatedCSSOMPrimitiveValue.h"
41 #include "FontCascade.h"
42 #include "Length.h"
43 #include "NodeRenderStyle.h"
44 #include "Pair.h"
45 #include "Rect.h"
46 #include "RenderStyle.h"
47 #include "RenderView.h"
48 #include <wtf/NeverDestroyed.h>
49 #include <wtf/StdLibExtras.h>
50 #include <wtf/text/StringBuilder.h>
51 #include <wtf/text/StringConcatenateNumbers.h>
53 namespace WebCore {
55 static inline bool isValidCSSUnitTypeForDoubleConversion(CSSUnitType unitType)
57 switch (unitType) {
58 case CSSUnitType::CSS_CALC:
59 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
60 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
61 case CSSUnitType::CSS_CHS:
62 case CSSUnitType::CSS_IC:
63 case CSSUnitType::CSS_CM:
64 case CSSUnitType::CSS_DEG:
65 case CSSUnitType::CSS_DIMENSION:
66 case CSSUnitType::CSS_DVB:
67 case CSSUnitType::CSS_DVH:
68 case CSSUnitType::CSS_DVI:
69 case CSSUnitType::CSS_DVMAX:
70 case CSSUnitType::CSS_DVMIN:
71 case CSSUnitType::CSS_DVW:
72 case CSSUnitType::CSS_EMS:
73 case CSSUnitType::CSS_EXS:
74 case CSSUnitType::CSS_FR:
75 case CSSUnitType::CSS_GRAD:
76 case CSSUnitType::CSS_HZ:
77 case CSSUnitType::CSS_IN:
78 case CSSUnitType::CSS_KHZ:
79 case CSSUnitType::CSS_MM:
80 case CSSUnitType::CSS_MS:
81 case CSSUnitType::CSS_NUMBER:
82 case CSSUnitType::CSS_INTEGER:
83 case CSSUnitType::CSS_PC:
84 case CSSUnitType::CSS_PERCENTAGE:
85 case CSSUnitType::CSS_PT:
86 case CSSUnitType::CSS_PX:
87 case CSSUnitType::CSS_Q:
88 case CSSUnitType::CSS_LHS:
89 case CSSUnitType::CSS_LVB:
90 case CSSUnitType::CSS_LVH:
91 case CSSUnitType::CSS_LVI:
92 case CSSUnitType::CSS_LVMAX:
93 case CSSUnitType::CSS_LVMIN:
94 case CSSUnitType::CSS_LVW:
95 case CSSUnitType::CSS_RLHS:
96 case CSSUnitType::CSS_QUIRKY_EMS:
97 case CSSUnitType::CSS_RAD:
98 case CSSUnitType::CSS_REMS:
99 case CSSUnitType::CSS_S:
100 case CSSUnitType::CSS_SVB:
101 case CSSUnitType::CSS_SVH:
102 case CSSUnitType::CSS_SVI:
103 case CSSUnitType::CSS_SVMAX:
104 case CSSUnitType::CSS_SVMIN:
105 case CSSUnitType::CSS_SVW:
106 case CSSUnitType::CSS_TURN:
107 case CSSUnitType::CSS_VB:
108 case CSSUnitType::CSS_VH:
109 case CSSUnitType::CSS_VI:
110 case CSSUnitType::CSS_VMAX:
111 case CSSUnitType::CSS_VMIN:
112 case CSSUnitType::CSS_VW:
113 case CSSUnitType::CSS_DPCM:
114 case CSSUnitType::CSS_DPI:
115 case CSSUnitType::CSS_DPPX:
116 case CSSUnitType::CSS_X:
117 case CSSUnitType::CSS_CQW:
118 case CSSUnitType::CSS_CQH:
119 case CSSUnitType::CSS_CQI:
120 case CSSUnitType::CSS_CQB:
121 case CSSUnitType::CSS_CQMIN:
122 case CSSUnitType::CSS_CQMAX:
123 return true;
124 case CSSUnitType::CSS_ATTR:
125 case CSSUnitType::CSS_COUNTER:
126 case CSSUnitType::CSS_COUNTER_NAME:
127 case CSSUnitType::CSS_FONT_FAMILY:
128 case CSSUnitType::CustomIdent:
129 case CSSUnitType::CSS_PAIR:
130 case CSSUnitType::CSS_PROPERTY_ID:
131 case CSSUnitType::CSS_QUAD:
132 case CSSUnitType::CSS_RECT:
133 case CSSUnitType::CSS_RGBCOLOR:
134 case CSSUnitType::CSS_SHAPE:
135 case CSSUnitType::CSS_STRING:
136 case CSSUnitType::CSS_UNICODE_RANGE:
137 case CSSUnitType::CSS_UNKNOWN:
138 case CSSUnitType::CSS_URI:
139 case CSSUnitType::CSS_VALUE_ID:
140 return false;
141 case CSSUnitType::CSS_IDENT:
142 break;
145 ASSERT_NOT_REACHED();
146 return false;
149 #if ASSERT_ENABLED
151 static inline bool isStringType(CSSUnitType type)
153 switch (type) {
154 case CSSUnitType::CSS_STRING:
155 case CSSUnitType::CustomIdent:
156 case CSSUnitType::CSS_URI:
157 case CSSUnitType::CSS_ATTR:
158 case CSSUnitType::CSS_COUNTER_NAME:
159 return true;
160 case CSSUnitType::CSS_CALC:
161 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
162 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
163 case CSSUnitType::CSS_CHS:
164 case CSSUnitType::CSS_IC:
165 case CSSUnitType::CSS_CM:
166 case CSSUnitType::CSS_COUNTER:
167 case CSSUnitType::CSS_DEG:
168 case CSSUnitType::CSS_DIMENSION:
169 case CSSUnitType::CSS_DPCM:
170 case CSSUnitType::CSS_DPI:
171 case CSSUnitType::CSS_DPPX:
172 case CSSUnitType::CSS_DVB:
173 case CSSUnitType::CSS_DVH:
174 case CSSUnitType::CSS_DVI:
175 case CSSUnitType::CSS_DVMAX:
176 case CSSUnitType::CSS_DVMIN:
177 case CSSUnitType::CSS_DVW:
178 case CSSUnitType::CSS_X:
179 case CSSUnitType::CSS_EMS:
180 case CSSUnitType::CSS_EXS:
181 case CSSUnitType::CSS_FONT_FAMILY:
182 case CSSUnitType::CSS_FR:
183 case CSSUnitType::CSS_GRAD:
184 case CSSUnitType::CSS_HZ:
185 case CSSUnitType::CSS_IDENT:
186 case CSSUnitType::CSS_IN:
187 case CSSUnitType::CSS_KHZ:
188 case CSSUnitType::CSS_LVB:
189 case CSSUnitType::CSS_LVH:
190 case CSSUnitType::CSS_LVI:
191 case CSSUnitType::CSS_LVMAX:
192 case CSSUnitType::CSS_LVMIN:
193 case CSSUnitType::CSS_LVW:
194 case CSSUnitType::CSS_MM:
195 case CSSUnitType::CSS_MS:
196 case CSSUnitType::CSS_NUMBER:
197 case CSSUnitType::CSS_INTEGER:
198 case CSSUnitType::CSS_PAIR:
199 case CSSUnitType::CSS_PC:
200 case CSSUnitType::CSS_PERCENTAGE:
201 case CSSUnitType::CSS_PROPERTY_ID:
202 case CSSUnitType::CSS_PT:
203 case CSSUnitType::CSS_PX:
204 case CSSUnitType::CSS_Q:
205 case CSSUnitType::CSS_LHS:
206 case CSSUnitType::CSS_RLHS:
207 case CSSUnitType::CSS_QUAD:
208 case CSSUnitType::CSS_QUIRKY_EMS:
209 case CSSUnitType::CSS_RAD:
210 case CSSUnitType::CSS_RECT:
211 case CSSUnitType::CSS_REMS:
212 case CSSUnitType::CSS_RGBCOLOR:
213 case CSSUnitType::CSS_S:
214 case CSSUnitType::CSS_SVB:
215 case CSSUnitType::CSS_SVH:
216 case CSSUnitType::CSS_SVI:
217 case CSSUnitType::CSS_SVMAX:
218 case CSSUnitType::CSS_SVMIN:
219 case CSSUnitType::CSS_SVW:
220 case CSSUnitType::CSS_SHAPE:
221 case CSSUnitType::CSS_TURN:
222 case CSSUnitType::CSS_UNICODE_RANGE:
223 case CSSUnitType::CSS_UNKNOWN:
224 case CSSUnitType::CSS_VALUE_ID:
225 case CSSUnitType::CSS_VB:
226 case CSSUnitType::CSS_VH:
227 case CSSUnitType::CSS_VI:
228 case CSSUnitType::CSS_VMAX:
229 case CSSUnitType::CSS_VMIN:
230 case CSSUnitType::CSS_VW:
231 case CSSUnitType::CSS_CQW:
232 case CSSUnitType::CSS_CQH:
233 case CSSUnitType::CSS_CQI:
234 case CSSUnitType::CSS_CQB:
235 case CSSUnitType::CSS_CQMIN:
236 case CSSUnitType::CSS_CQMAX:
237 return false;
240 ASSERT_NOT_REACHED();
241 return false;
244 #endif // ASSERT_ENABLED
246 typedef HashMap<const CSSPrimitiveValue*, String> CSSTextCache;
247 static CSSTextCache& cssTextCache()
249 static NeverDestroyed<CSSTextCache> cache;
250 return cache;
253 CSSUnitType CSSPrimitiveValue::primitiveType() const
255 // FIXME: Use a switch statement here.
257 if (primitiveUnitType() == CSSUnitType::CSS_PROPERTY_ID || primitiveUnitType() == CSSUnitType::CSS_VALUE_ID || primitiveUnitType() == CSSUnitType::CustomIdent)
258 return CSSUnitType::CSS_IDENT;
260 // Web-exposed content expects font family values to have CSSUnitType::CSS_STRING primitive type
261 // so we need to map our internal CSSUnitType::CSS_FONT_FAMILY type here.
262 if (primitiveUnitType() == CSSUnitType::CSS_FONT_FAMILY)
263 return CSSUnitType::CSS_STRING;
265 if (primitiveUnitType() != CSSUnitType::CSS_CALC)
266 return primitiveUnitType();
268 switch (m_value.calc->category()) {
269 case CalculationCategory::Number:
270 return CSSUnitType::CSS_NUMBER;
271 case CalculationCategory::Percent:
272 return CSSUnitType::CSS_PERCENTAGE;
273 case CalculationCategory::PercentNumber:
274 return CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER;
275 case CalculationCategory::PercentLength:
276 return CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH;
277 case CalculationCategory::Length:
278 case CalculationCategory::Angle:
279 case CalculationCategory::Time:
280 case CalculationCategory::Frequency:
281 return m_value.calc->primitiveType();
282 case CalculationCategory::Other:
283 return CSSUnitType::CSS_UNKNOWN;
285 return CSSUnitType::CSS_UNKNOWN;
288 static const AtomString& propertyName(CSSPropertyID propertyID)
290 ASSERT_ARG(propertyID, (propertyID >= firstCSSProperty && propertyID < firstCSSProperty + numCSSProperties));
292 return getPropertyNameAtomString(propertyID);
295 static const AtomString& valueName(CSSValueID valueID)
297 ASSERT_ARG(valueID, (valueID >= firstCSSValueKeyword && valueID <= lastCSSValueKeyword));
299 return getValueNameAtomString(valueID);
302 CSSPrimitiveValue::CSSPrimitiveValue(CSSValueID valueID)
303 : CSSValue(PrimitiveClass)
305 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
306 m_value.valueID = valueID;
309 CSSPrimitiveValue::CSSPrimitiveValue(CSSPropertyID propertyID)
310 : CSSValue(PrimitiveClass)
312 setPrimitiveUnitType(CSSUnitType::CSS_PROPERTY_ID);
313 m_value.propertyID = propertyID;
316 CSSPrimitiveValue::CSSPrimitiveValue(double num, CSSUnitType type)
317 : CSSValue(PrimitiveClass)
319 setPrimitiveUnitType(type);
320 m_value.num = num;
323 CSSPrimitiveValue::CSSPrimitiveValue(const String& string, CSSUnitType type)
324 : CSSValue(PrimitiveClass)
326 ASSERT(isStringType(type));
327 setPrimitiveUnitType(type);
328 if ((m_value.string = string.impl()))
329 m_value.string->ref();
332 CSSPrimitiveValue::CSSPrimitiveValue(const Color& color)
333 : CSSValue(PrimitiveClass)
335 setPrimitiveUnitType(CSSUnitType::CSS_RGBCOLOR);
336 m_value.color = new Color(color);
339 CSSPrimitiveValue::CSSPrimitiveValue(const Length& length)
340 : CSSValue(PrimitiveClass)
342 init(length);
345 CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, const RenderStyle& style)
346 : CSSValue(PrimitiveClass)
348 switch (length.type()) {
349 case LengthType::Auto:
350 case LengthType::Content:
351 case LengthType::Intrinsic:
352 case LengthType::MinIntrinsic:
353 case LengthType::MinContent:
354 case LengthType::MaxContent:
355 case LengthType::FillAvailable:
356 case LengthType::FitContent:
357 case LengthType::Percent:
358 init(length);
359 return;
360 case LengthType::Fixed:
361 setPrimitiveUnitType(CSSUnitType::CSS_PX);
362 m_value.num = adjustFloatForAbsoluteZoom(length.value(), style);
363 return;
364 case LengthType::Calculated:
365 init(CSSCalcValue::create(length.calculationValue(), style));
366 return;
367 case LengthType::Relative:
368 case LengthType::Undefined:
369 ASSERT_NOT_REACHED();
370 return;
372 ASSERT_NOT_REACHED();
375 CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize, const RenderStyle& style)
376 : CSSValue(PrimitiveClass)
378 init(lengthSize, style);
381 CSSPrimitiveValue::CSSPrimitiveValue(StaticCSSValueTag, CSSValueID valueID)
382 : CSSPrimitiveValue(valueID)
384 makeStatic();
387 CSSPrimitiveValue::CSSPrimitiveValue(StaticCSSValueTag, const Color& color)
388 : CSSPrimitiveValue(color)
390 makeStatic();
393 CSSPrimitiveValue::CSSPrimitiveValue(StaticCSSValueTag, double num, CSSUnitType type)
394 : CSSPrimitiveValue(num, type)
396 makeStatic();
399 CSSPrimitiveValue::CSSPrimitiveValue(StaticCSSValueTag, ImplicitInitialValueTag)
400 : CSSPrimitiveValue(CSSValueInitial)
402 m_isImplicit = true;
403 makeStatic();
406 void CSSPrimitiveValue::init(const Length& length)
408 switch (length.type()) {
409 case LengthType::Auto:
410 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
411 m_value.valueID = CSSValueAuto;
412 return;
413 case LengthType::Content:
414 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
415 m_value.valueID = CSSValueContent;
416 return;
417 case LengthType::Fixed:
418 setPrimitiveUnitType(CSSUnitType::CSS_PX);
419 m_value.num = length.value();
420 return;
421 case LengthType::Intrinsic:
422 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
423 m_value.valueID = CSSValueIntrinsic;
424 return;
425 case LengthType::MinIntrinsic:
426 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
427 m_value.valueID = CSSValueMinIntrinsic;
428 return;
429 case LengthType::MinContent:
430 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
431 m_value.valueID = CSSValueMinContent;
432 return;
433 case LengthType::MaxContent:
434 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
435 m_value.valueID = CSSValueMaxContent;
436 return;
437 case LengthType::FillAvailable:
438 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
439 m_value.valueID = CSSValueWebkitFillAvailable;
440 return;
441 case LengthType::FitContent:
442 setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
443 m_value.valueID = CSSValueFitContent;
444 return;
445 case LengthType::Percent:
446 setPrimitiveUnitType(CSSUnitType::CSS_PERCENTAGE);
447 ASSERT(std::isfinite(length.percent()));
448 m_value.num = length.percent();
449 return;
450 case LengthType::Calculated:
451 case LengthType::Relative:
452 case LengthType::Undefined:
453 ASSERT_NOT_REACHED();
454 return;
456 ASSERT_NOT_REACHED();
459 void CSSPrimitiveValue::init(const LengthSize& lengthSize, const RenderStyle& style)
461 setPrimitiveUnitType(CSSUnitType::CSS_PAIR);
462 m_hasCachedCSSText = false;
463 m_value.pair = &Pair::create(create(lengthSize.width, style), create(lengthSize.height, style)).leakRef();
466 void CSSPrimitiveValue::init(Ref<Counter>&& counter)
468 setPrimitiveUnitType(CSSUnitType::CSS_COUNTER);
469 m_hasCachedCSSText = false;
470 m_value.counter = &counter.leakRef();
473 void CSSPrimitiveValue::init(Ref<Rect>&& r)
475 setPrimitiveUnitType(CSSUnitType::CSS_RECT);
476 m_hasCachedCSSText = false;
477 m_value.rect = &r.leakRef();
480 void CSSPrimitiveValue::init(Ref<Quad>&& quad)
482 setPrimitiveUnitType(CSSUnitType::CSS_QUAD);
483 m_hasCachedCSSText = false;
484 m_value.quad = &quad.leakRef();
487 void CSSPrimitiveValue::init(Ref<Pair>&& p)
489 setPrimitiveUnitType(CSSUnitType::CSS_PAIR);
490 m_hasCachedCSSText = false;
491 m_value.pair = &p.leakRef();
494 void CSSPrimitiveValue::init(Ref<CSSBasicShape>&& shape)
496 setPrimitiveUnitType(CSSUnitType::CSS_SHAPE);
497 m_hasCachedCSSText = false;
498 m_value.shape = &shape.leakRef();
501 void CSSPrimitiveValue::init(RefPtr<CSSCalcValue>&& c)
503 // FIXME (231111): This init should take Ref<CSSCalcValue> instead.
504 if (!c)
505 return;
506 setPrimitiveUnitType(CSSUnitType::CSS_CALC);
507 m_hasCachedCSSText = false;
508 m_value.calc = c.leakRef();
511 CSSPrimitiveValue::~CSSPrimitiveValue()
513 cleanup();
516 void CSSPrimitiveValue::cleanup()
518 auto type = primitiveUnitType();
519 switch (type) {
520 case CSSUnitType::CSS_STRING:
521 case CSSUnitType::CustomIdent:
522 case CSSUnitType::CSS_URI:
523 case CSSUnitType::CSS_ATTR:
524 case CSSUnitType::CSS_COUNTER_NAME:
525 if (m_value.string)
526 m_value.string->deref();
527 break;
528 case CSSUnitType::CSS_COUNTER:
529 m_value.counter->deref();
530 break;
531 case CSSUnitType::CSS_RECT:
532 m_value.rect->deref();
533 break;
534 case CSSUnitType::CSS_QUAD:
535 m_value.quad->deref();
536 break;
537 case CSSUnitType::CSS_PAIR:
538 m_value.pair->deref();
539 break;
540 case CSSUnitType::CSS_CALC:
541 if (m_value.calc)
542 m_value.calc->deref();
543 break;
544 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
545 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
546 ASSERT_NOT_REACHED();
547 break;
548 case CSSUnitType::CSS_SHAPE:
549 m_value.shape->deref();
550 break;
551 case CSSUnitType::CSS_FONT_FAMILY:
552 ASSERT(m_value.fontFamily);
553 delete m_value.fontFamily;
554 m_value.fontFamily = nullptr;
555 break;
556 case CSSUnitType::CSS_RGBCOLOR:
557 ASSERT(m_value.color);
558 delete m_value.color;
559 m_value.color = nullptr;
560 break;
561 case CSSUnitType::CSS_DIMENSION:
562 case CSSUnitType::CSS_NUMBER:
563 case CSSUnitType::CSS_INTEGER:
564 case CSSUnitType::CSS_PERCENTAGE:
565 case CSSUnitType::CSS_EMS:
566 case CSSUnitType::CSS_QUIRKY_EMS:
567 case CSSUnitType::CSS_EXS:
568 case CSSUnitType::CSS_REMS:
569 case CSSUnitType::CSS_CHS:
570 case CSSUnitType::CSS_IC:
571 case CSSUnitType::CSS_PX:
572 case CSSUnitType::CSS_CM:
573 case CSSUnitType::CSS_MM:
574 case CSSUnitType::CSS_IN:
575 case CSSUnitType::CSS_PT:
576 case CSSUnitType::CSS_PC:
577 case CSSUnitType::CSS_DEG:
578 case CSSUnitType::CSS_RAD:
579 case CSSUnitType::CSS_GRAD:
580 case CSSUnitType::CSS_MS:
581 case CSSUnitType::CSS_S:
582 case CSSUnitType::CSS_HZ:
583 case CSSUnitType::CSS_KHZ:
584 case CSSUnitType::CSS_TURN:
585 case CSSUnitType::CSS_VW:
586 case CSSUnitType::CSS_VH:
587 case CSSUnitType::CSS_VMIN:
588 case CSSUnitType::CSS_VMAX:
589 case CSSUnitType::CSS_VB:
590 case CSSUnitType::CSS_VI:
591 case CSSUnitType::CSS_SVW:
592 case CSSUnitType::CSS_SVH:
593 case CSSUnitType::CSS_SVMIN:
594 case CSSUnitType::CSS_SVMAX:
595 case CSSUnitType::CSS_SVB:
596 case CSSUnitType::CSS_SVI:
597 case CSSUnitType::CSS_LVW:
598 case CSSUnitType::CSS_LVH:
599 case CSSUnitType::CSS_LVMIN:
600 case CSSUnitType::CSS_LVMAX:
601 case CSSUnitType::CSS_LVB:
602 case CSSUnitType::CSS_LVI:
603 case CSSUnitType::CSS_DVW:
604 case CSSUnitType::CSS_DVH:
605 case CSSUnitType::CSS_DVMIN:
606 case CSSUnitType::CSS_DVMAX:
607 case CSSUnitType::CSS_DVB:
608 case CSSUnitType::CSS_DVI:
609 case CSSUnitType::CSS_DPPX:
610 case CSSUnitType::CSS_X:
611 case CSSUnitType::CSS_DPI:
612 case CSSUnitType::CSS_DPCM:
613 case CSSUnitType::CSS_FR:
614 case CSSUnitType::CSS_Q:
615 case CSSUnitType::CSS_LHS:
616 case CSSUnitType::CSS_RLHS:
617 case CSSUnitType::CSS_IDENT:
618 case CSSUnitType::CSS_UNKNOWN:
619 case CSSUnitType::CSS_UNICODE_RANGE:
620 case CSSUnitType::CSS_PROPERTY_ID:
621 case CSSUnitType::CSS_VALUE_ID:
622 case CSSUnitType::CSS_CQW:
623 case CSSUnitType::CSS_CQH:
624 case CSSUnitType::CSS_CQI:
625 case CSSUnitType::CSS_CQB:
626 case CSSUnitType::CSS_CQMIN:
627 case CSSUnitType::CSS_CQMAX:
628 ASSERT(!isStringType(type));
629 break;
631 setPrimitiveUnitType(CSSUnitType::CSS_UNKNOWN);
632 if (m_hasCachedCSSText) {
633 cssTextCache().remove(this);
634 m_hasCachedCSSText = false;
638 double CSSPrimitiveValue::computeDegrees() const
640 return computeDegrees(primitiveType(), doubleValue());
643 template<> int CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
645 return roundForImpreciseConversion<int>(computeLengthDouble(conversionData));
648 template<> unsigned CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
650 return roundForImpreciseConversion<unsigned>(computeLengthDouble(conversionData));
653 template<> Length CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
655 return Length(clampTo<double>(computeLengthDouble(conversionData), minValueForCssLength, maxValueForCssLength), LengthType::Fixed);
658 template<> short CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
660 return roundForImpreciseConversion<short>(computeLengthDouble(conversionData));
663 template<> unsigned short CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
665 return roundForImpreciseConversion<unsigned short>(computeLengthDouble(conversionData));
668 template<> float CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
670 return static_cast<float>(computeLengthDouble(conversionData));
673 template<> double CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
675 return computeLengthDouble(conversionData);
678 template<> LayoutUnit CSSPrimitiveValue::computeLength(const CSSToLengthConversionData& conversionData) const
680 return LayoutUnit(computeLengthDouble(conversionData));
683 double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& conversionData) const
685 if (primitiveUnitType() == CSSUnitType::CSS_CALC) {
686 // The multiplier and factor is applied to each value in the calc expression individually
687 return m_value.calc->computeLengthPx(conversionData);
690 return computeNonCalcLengthDouble(conversionData, primitiveType(), m_value.num);
693 static constexpr double mmPerInch = 25.4;
694 static constexpr double cmPerInch = 2.54;
695 static constexpr double QPerInch = 25.4 * 4.0;
697 static double lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis logicalAxis, const FloatSize& size, const RenderStyle* rootElementStyle)
699 if (!rootElementStyle)
700 return 0;
702 switch (mapLogicalAxisToPhysicalAxis(makeTextFlow(rootElementStyle->writingMode(), rootElementStyle->direction()), logicalAxis)) {
703 case BoxAxis::Horizontal:
704 return size.width();
706 case BoxAxis::Vertical:
707 return size.height();
710 RELEASE_ASSERT_NOT_REACHED();
713 static double lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis logicalAxis, const FloatSize& size, const RenderView& renderView)
715 const auto* rootElement = renderView.document().documentElement();
716 if (!rootElement)
717 return 0;
719 return lengthOfViewportPhysicalAxisForLogicalAxis(logicalAxis, size, rootElement->renderStyle());
722 double CSSPrimitiveValue::computeUnzoomedNonCalcLengthDouble(CSSUnitType primitiveType, double value, CSSPropertyID propertyToCompute, const FontMetrics* fontMetrics, const FontCascadeDescription* fontDescription, const FontCascadeDescription* rootFontDescription, const RenderView* renderView)
724 switch (primitiveType) {
725 case CSSUnitType::CSS_EMS:
726 case CSSUnitType::CSS_QUIRKY_EMS:
727 ASSERT(fontDescription);
728 return ((propertyToCompute == CSSPropertyFontSize) ? fontDescription->specifiedSize() : fontDescription->computedSize()) * value;
729 case CSSUnitType::CSS_EXS:
730 ASSERT(fontMetrics);
731 if (fontMetrics->hasXHeight())
732 return fontMetrics->xHeight() * value;
733 ASSERT(fontDescription);
734 return ((propertyToCompute == CSSPropertyFontSize) ? fontDescription->specifiedSize() : fontDescription->computedSize()) / 2.0 * value;
735 case CSSUnitType::CSS_REMS:
736 if (!rootFontDescription)
737 return value;
738 return ((propertyToCompute == CSSPropertyFontSize) ? rootFontDescription->specifiedSize() : rootFontDescription->computedSize()) * value;
739 case CSSUnitType::CSS_CHS:
740 ASSERT(fontMetrics);
741 ASSERT(fontDescription);
742 return fontMetrics->zeroWidth().value_or(fontDescription->computedSize() / 2) * value;
743 case CSSUnitType::CSS_IC:
744 ASSERT(fontMetrics);
745 return fontMetrics->ideogramWidth() * value;
746 case CSSUnitType::CSS_PX:
747 return value;
748 case CSSUnitType::CSS_CM:
749 return cssPixelsPerInch / cmPerInch * value;
750 case CSSUnitType::CSS_MM:
751 return cssPixelsPerInch / mmPerInch * value;
752 case CSSUnitType::CSS_Q:
753 return cssPixelsPerInch / QPerInch * value;
754 case CSSUnitType::CSS_LHS:
755 case CSSUnitType::CSS_RLHS:
756 ASSERT_NOT_REACHED();
757 return -1.0;
758 case CSSUnitType::CSS_IN:
759 return cssPixelsPerInch * value;
760 case CSSUnitType::CSS_PT:
761 return cssPixelsPerInch / 72.0 * value;
762 case CSSUnitType::CSS_PC:
763 // 1 pc == 12 pt
764 return cssPixelsPerInch * 12.0 / 72.0 * value;
765 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
766 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
767 ASSERT_NOT_REACHED();
768 return -1.0;
769 case CSSUnitType::CSS_VH:
770 return renderView ? renderView->sizeForCSSDefaultViewportUnits().height() / 100.0 * value : 0;
771 case CSSUnitType::CSS_VW:
772 return renderView ? renderView->sizeForCSSDefaultViewportUnits().width() / 100.0 * value : 0;
773 case CSSUnitType::CSS_VMAX:
774 return renderView ? renderView->sizeForCSSDefaultViewportUnits().maxDimension() / 100.0 * value : value;
775 case CSSUnitType::CSS_VMIN:
776 return renderView ? renderView->sizeForCSSDefaultViewportUnits().minDimension() / 100.0 * value : value;
777 case CSSUnitType::CSS_VB:
778 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, renderView->sizeForCSSDefaultViewportUnits(), *renderView) / 100.0 * value : 0;
779 case CSSUnitType::CSS_VI:
780 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, renderView->sizeForCSSDefaultViewportUnits(), *renderView) / 100.0 * value : 0;
781 case CSSUnitType::CSS_SVH:
782 return renderView ? renderView->sizeForCSSSmallViewportUnits().height() / 100.0 * value : 0;
783 case CSSUnitType::CSS_SVW:
784 return renderView ? renderView->sizeForCSSSmallViewportUnits().width() / 100.0 * value : 0;
785 case CSSUnitType::CSS_SVMAX:
786 return renderView ? renderView->sizeForCSSSmallViewportUnits().maxDimension() / 100.0 * value : value;
787 case CSSUnitType::CSS_SVMIN:
788 return renderView ? renderView->sizeForCSSSmallViewportUnits().minDimension() / 100.0 * value : value;
789 case CSSUnitType::CSS_SVB:
790 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, renderView->sizeForCSSSmallViewportUnits(), *renderView) / 100.0 * value : 0;
791 case CSSUnitType::CSS_SVI:
792 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, renderView->sizeForCSSSmallViewportUnits(), *renderView) / 100.0 * value : 0;
793 case CSSUnitType::CSS_LVH:
794 return renderView ? renderView->sizeForCSSLargeViewportUnits().height() / 100.0 * value : 0;
795 case CSSUnitType::CSS_LVW:
796 return renderView ? renderView->sizeForCSSLargeViewportUnits().width() / 100.0 * value : 0;
797 case CSSUnitType::CSS_LVMAX:
798 return renderView ? renderView->sizeForCSSLargeViewportUnits().maxDimension() / 100.0 * value : value;
799 case CSSUnitType::CSS_LVMIN:
800 return renderView ? renderView->sizeForCSSLargeViewportUnits().minDimension() / 100.0 * value : value;
801 case CSSUnitType::CSS_LVB:
802 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, renderView->sizeForCSSLargeViewportUnits(), *renderView) / 100.0 * value : 0;
803 case CSSUnitType::CSS_LVI:
804 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, renderView->sizeForCSSLargeViewportUnits(), *renderView) / 100.0 * value : 0;
805 case CSSUnitType::CSS_DVH:
806 return renderView ? renderView->sizeForCSSDynamicViewportUnits().height() / 100.0 * value : 0;
807 case CSSUnitType::CSS_DVW:
808 return renderView ? renderView->sizeForCSSDynamicViewportUnits().width() / 100.0 * value : 0;
809 case CSSUnitType::CSS_DVMAX:
810 return renderView ? renderView->sizeForCSSDynamicViewportUnits().maxDimension() / 100.0 * value : value;
811 case CSSUnitType::CSS_DVMIN:
812 return renderView ? renderView->sizeForCSSDynamicViewportUnits().minDimension() / 100.0 * value : value;
813 case CSSUnitType::CSS_DVB:
814 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, renderView->sizeForCSSDynamicViewportUnits(), *renderView) / 100.0 * value : 0;
815 case CSSUnitType::CSS_DVI:
816 return renderView ? lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, renderView->sizeForCSSDynamicViewportUnits(), *renderView) / 100.0 * value : 0;
817 default:
818 ASSERT_NOT_REACHED();
819 return -1.0;
823 double CSSPrimitiveValue::computeNonCalcLengthDouble(const CSSToLengthConversionData& conversionData, CSSUnitType primitiveType, double value)
825 auto selectContainerRenderer = [&](CQ::Axis axis) -> const RenderBox* {
826 if (!conversionData.element())
827 return nullptr;
828 // FIXME: Use cached query containers when available.
829 auto* container = Style::ContainerQueryEvaluator::selectContainer(axis, nullString(), *conversionData.element());
830 if (!container)
831 return nullptr;
832 return dynamicDowncast<RenderBox>(container->renderer());
835 switch (primitiveType) {
836 case CSSUnitType::CSS_EMS:
837 case CSSUnitType::CSS_QUIRKY_EMS:
838 ASSERT(conversionData.style());
839 value = computeUnzoomedNonCalcLengthDouble(primitiveType, value, conversionData.propertyToCompute(), nullptr, &conversionData.style()->fontDescription());
840 break;
842 case CSSUnitType::CSS_EXS:
843 // FIXME: We have a bug right now where the zoom will be applied twice to EX units.
844 // We really need to compute EX using fontMetrics for the original specifiedSize and not use
845 // our actual constructed rendering font.
846 ASSERT(conversionData.style());
847 value = computeUnzoomedNonCalcLengthDouble(primitiveType, value, conversionData.propertyToCompute(), &conversionData.style()->metricsOfPrimaryFont(), &conversionData.style()->fontDescription());
848 break;
850 case CSSUnitType::CSS_REMS:
851 value = computeUnzoomedNonCalcLengthDouble(primitiveType, value, conversionData.propertyToCompute(), nullptr, nullptr, conversionData.rootStyle() ? &conversionData.rootStyle()->fontDescription() : nullptr);
852 break;
854 case CSSUnitType::CSS_CHS:
855 case CSSUnitType::CSS_IC:
856 ASSERT(conversionData.style());
857 value = computeUnzoomedNonCalcLengthDouble(primitiveType, value, conversionData.propertyToCompute(), &conversionData.style()->metricsOfPrimaryFont(), &conversionData.style()->fontDescription());
858 break;
860 case CSSUnitType::CSS_PX:
861 case CSSUnitType::CSS_CM:
862 case CSSUnitType::CSS_MM:
863 case CSSUnitType::CSS_Q:
864 case CSSUnitType::CSS_IN:
865 case CSSUnitType::CSS_PT:
866 case CSSUnitType::CSS_PC:
867 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
868 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
869 value = computeUnzoomedNonCalcLengthDouble(primitiveType, value, conversionData.propertyToCompute());
870 break;
872 case CSSUnitType::CSS_VH:
873 return value * conversionData.defaultViewportFactor().height();
875 case CSSUnitType::CSS_VW:
876 return value * conversionData.defaultViewportFactor().width();
878 case CSSUnitType::CSS_VMAX:
879 return value * conversionData.defaultViewportFactor().maxDimension();
881 case CSSUnitType::CSS_VMIN:
882 return value * conversionData.defaultViewportFactor().minDimension();
884 case CSSUnitType::CSS_VB:
885 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.defaultViewportFactor(), conversionData.rootStyle());
887 case CSSUnitType::CSS_VI:
888 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.defaultViewportFactor(), conversionData.rootStyle());
890 case CSSUnitType::CSS_SVH:
891 return value * conversionData.smallViewportFactor().height();
893 case CSSUnitType::CSS_SVW:
894 return value * conversionData.smallViewportFactor().width();
896 case CSSUnitType::CSS_SVMAX:
897 return value * conversionData.smallViewportFactor().maxDimension();
899 case CSSUnitType::CSS_SVMIN:
900 return value * conversionData.smallViewportFactor().minDimension();
902 case CSSUnitType::CSS_SVB:
903 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.smallViewportFactor(), conversionData.rootStyle());
905 case CSSUnitType::CSS_SVI:
906 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.smallViewportFactor(), conversionData.rootStyle());
908 case CSSUnitType::CSS_LVH:
909 return value * conversionData.largeViewportFactor().height();
911 case CSSUnitType::CSS_LVW:
912 return value * conversionData.largeViewportFactor().width();
914 case CSSUnitType::CSS_LVMAX:
915 return value * conversionData.largeViewportFactor().maxDimension();
917 case CSSUnitType::CSS_LVMIN:
918 return value * conversionData.largeViewportFactor().minDimension();
920 case CSSUnitType::CSS_LVB:
921 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.largeViewportFactor(), conversionData.rootStyle());
923 case CSSUnitType::CSS_LVI:
924 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.largeViewportFactor(), conversionData.rootStyle());
926 case CSSUnitType::CSS_DVH:
927 return value * conversionData.dynamicViewportFactor().height();
929 case CSSUnitType::CSS_DVW:
930 return value * conversionData.dynamicViewportFactor().width();
932 case CSSUnitType::CSS_DVMAX:
933 return value * conversionData.dynamicViewportFactor().maxDimension();
935 case CSSUnitType::CSS_DVMIN:
936 return value * conversionData.dynamicViewportFactor().minDimension();
938 case CSSUnitType::CSS_DVB:
939 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.dynamicViewportFactor(), conversionData.rootStyle());
941 case CSSUnitType::CSS_DVI:
942 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.dynamicViewportFactor(), conversionData.rootStyle());
944 case CSSUnitType::CSS_LHS:
945 ASSERT(conversionData.style());
946 if (conversionData.computingLineHeight() || conversionData.computingFontSize()) {
947 // Try to get the parent's computed line-height, or fall back to the initial line-height of this element's font spacing.
948 value *= conversionData.parentStyle() ? conversionData.parentStyle()->computedLineHeight() : conversionData.style()->metricsOfPrimaryFont().lineSpacing();
949 } else
950 value *= conversionData.style()->computedLineHeight();
951 break;
953 case CSSUnitType::CSS_CQW: {
954 if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Width))
955 return containerRenderer->width() * value / 100;
956 return value * conversionData.smallViewportFactor().width();
959 case CSSUnitType::CSS_CQH: {
960 if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Height))
961 return containerRenderer->height() * value / 100;
962 return value * conversionData.smallViewportFactor().height();
965 case CSSUnitType::CSS_CQI: {
966 if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Inline))
967 return containerRenderer->logicalWidth() * value / 100;
968 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Inline, conversionData.smallViewportFactor(), conversionData.rootStyle());
971 case CSSUnitType::CSS_CQB: {
972 if (auto* containerRenderer = selectContainerRenderer(CQ::Axis::Block))
973 return containerRenderer->logicalHeight() * value / 100;
974 return value * lengthOfViewportPhysicalAxisForLogicalAxis(LogicalBoxAxis::Block, conversionData.smallViewportFactor(), conversionData.rootStyle());
977 case CSSUnitType::CSS_CQMAX:
978 return std::max(computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQB, value), computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQI, value));
980 case CSSUnitType::CSS_CQMIN:
981 return std::min(computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQB, value), computeNonCalcLengthDouble(conversionData, CSSUnitType::CSS_CQI, value));
983 case CSSUnitType::CSS_RLHS:
984 if (conversionData.rootStyle()) {
985 if (conversionData.computingLineHeight() || conversionData.computingFontSize())
986 value *= conversionData.rootStyle()->computeLineHeight(conversionData.rootStyle()->specifiedLineHeight());
987 else
988 value *= conversionData.rootStyle()->computedLineHeight();
990 break;
992 default:
993 ASSERT_NOT_REACHED();
994 return -1.0;
997 // We do not apply the zoom factor when we are computing the value of the font-size property. The zooming
998 // for font sizes is much more complicated, since we have to worry about enforcing the minimum font size preference
999 // as well as enforcing the implicit "smart minimum."
1000 if (conversionData.computingFontSize() || isFontRelativeLength(primitiveType))
1001 return value;
1003 return value * conversionData.zoom();
1006 bool CSSPrimitiveValue::equalForLengthResolution(const RenderStyle& styleA, const RenderStyle& styleB)
1008 // These properties affect results of computeNonCalcLengthDouble above.
1009 if (styleA.fontDescription().computedSize() != styleB.fontDescription().computedSize())
1010 return false;
1011 if (styleA.fontDescription().specifiedSize() != styleB.fontDescription().specifiedSize())
1012 return false;
1014 if (styleA.metricsOfPrimaryFont().xHeight() != styleB.metricsOfPrimaryFont().xHeight())
1015 return false;
1016 if (styleA.metricsOfPrimaryFont().zeroWidth() != styleB.metricsOfPrimaryFont().zeroWidth())
1017 return false;
1019 if (styleA.zoom() != styleB.zoom())
1020 return false;
1022 return true;
1025 std::optional<double> CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(CSSUnitType unitType)
1027 // FIXME: the switch can be replaced by an array of scale factors.
1028 switch (unitType) {
1029 // These are "canonical" units in their respective categories.
1030 case CSSUnitType::CSS_PX:
1031 case CSSUnitType::CSS_DEG:
1032 case CSSUnitType::CSS_S:
1033 case CSSUnitType::CSS_HZ:
1034 case CSSUnitType::CSS_DPPX:
1035 return 1.0;
1037 case CSSUnitType::CSS_X:
1038 // This is semantically identical to (canonical) dppx
1039 return 1.0;
1041 case CSSUnitType::CSS_CM:
1042 return cssPixelsPerInch / cmPerInch;
1044 case CSSUnitType::CSS_DPCM:
1045 return cmPerInch / cssPixelsPerInch; // (2.54 cm/in)
1047 case CSSUnitType::CSS_MM:
1048 return cssPixelsPerInch / mmPerInch;
1050 case CSSUnitType::CSS_Q:
1051 return cssPixelsPerInch / QPerInch;
1053 case CSSUnitType::CSS_IN:
1054 return cssPixelsPerInch;
1056 case CSSUnitType::CSS_DPI:
1057 return 1 / cssPixelsPerInch;
1059 case CSSUnitType::CSS_PT:
1060 return cssPixelsPerInch / 72.0;
1062 case CSSUnitType::CSS_PC:
1063 return cssPixelsPerInch * 12.0 / 72.0; // 1 pc == 12 pt
1065 case CSSUnitType::CSS_RAD:
1066 return degreesPerRadianDouble;
1068 case CSSUnitType::CSS_GRAD:
1069 return degreesPerGradientDouble;
1071 case CSSUnitType::CSS_TURN:
1072 return degreesPerTurnDouble;
1074 case CSSUnitType::CSS_MS:
1075 return 0.001;
1076 case CSSUnitType::CSS_KHZ:
1077 return 1000;
1079 default:
1080 return std::nullopt;
1084 ExceptionOr<float> CSSPrimitiveValue::getFloatValue(CSSUnitType unitType) const
1086 auto result = doubleValueInternal(unitType);
1087 if (!result)
1088 return Exception { InvalidAccessError };
1089 return clampTo<float>(result.value());
1092 double CSSPrimitiveValue::doubleValue(CSSUnitType unitType) const
1094 return doubleValueInternal(unitType).value_or(0);
1097 double CSSPrimitiveValue::doubleValue() const
1099 return primitiveUnitType() != CSSUnitType::CSS_CALC ? m_value.num : m_value.calc->doubleValue();
1102 double CSSPrimitiveValue::doubleValueDividingBy100IfPercentage() const
1104 switch (primitiveUnitType()) {
1105 case CSSUnitType::CSS_CALC:
1106 return m_value.calc->primitiveType() == CSSUnitType::CSS_PERCENTAGE ? m_value.calc->doubleValue() / 100.0 : m_value.calc->doubleValue();
1108 case CSSUnitType::CSS_PERCENTAGE:
1109 return m_value.num / 100.0;
1111 default:
1112 return m_value.num;
1116 std::optional<bool> CSSPrimitiveValue::isZero() const
1118 if (primitiveUnitType() == CSSUnitType::CSS_CALC)
1119 return std::nullopt;
1120 return !m_value.num;
1123 std::optional<bool> CSSPrimitiveValue::isPositive() const
1125 if (primitiveUnitType() == CSSUnitType::CSS_CALC)
1126 return std::nullopt;
1127 return m_value.num > 0;
1130 std::optional<bool> CSSPrimitiveValue::isNegative() const
1132 if (primitiveUnitType() == CSSUnitType::CSS_CALC)
1133 return std::nullopt;
1134 return m_value.num < 0;
1137 bool CSSPrimitiveValue::isCenterPosition() const
1139 return valueID() == CSSValueCenter || doubleValue(CSSUnitType::CSS_PERCENTAGE) == 50;
1142 std::optional<double> CSSPrimitiveValue::doubleValueInternal(CSSUnitType requestedUnitType) const
1144 if (!isValidCSSUnitTypeForDoubleConversion(primitiveUnitType()) || !isValidCSSUnitTypeForDoubleConversion(requestedUnitType))
1145 return std::nullopt;
1147 CSSUnitType sourceUnitType = primitiveType();
1148 if (requestedUnitType == sourceUnitType || requestedUnitType == CSSUnitType::CSS_DIMENSION)
1149 return doubleValue();
1151 CSSUnitCategory sourceCategory = unitCategory(sourceUnitType);
1152 ASSERT(sourceCategory != CSSUnitCategory::Other);
1154 CSSUnitType targetUnitType = requestedUnitType;
1155 CSSUnitCategory targetCategory = unitCategory(targetUnitType);
1156 ASSERT(targetCategory != CSSUnitCategory::Other);
1158 // Cannot convert between unrelated unit categories if one of them is not CSSUnitCategory::Number.
1159 if (sourceCategory != targetCategory && sourceCategory != CSSUnitCategory::Number && targetCategory != CSSUnitCategory::Number)
1160 return std::nullopt;
1162 if (targetCategory == CSSUnitCategory::Number) {
1163 // We interpret conversion to CSSUnitType::CSS_NUMBER as conversion to a canonical unit in this value's category.
1164 targetUnitType = canonicalUnitTypeForCategory(sourceCategory);
1165 if (targetUnitType == CSSUnitType::CSS_UNKNOWN)
1166 return std::nullopt;
1169 if (sourceUnitType == CSSUnitType::CSS_NUMBER || sourceUnitType == CSSUnitType::CSS_INTEGER) {
1170 // We interpret conversion from CSSUnitType::CSS_NUMBER in the same way as CSSParser::validUnit() while using non-strict mode.
1171 sourceUnitType = canonicalUnitTypeForCategory(targetCategory);
1172 if (sourceUnitType == CSSUnitType::CSS_UNKNOWN)
1173 return std::nullopt;
1176 double convertedValue = doubleValue();
1178 // If we don't need to scale it, don't worry about if we can scale it.
1179 if (sourceUnitType == targetUnitType)
1180 return convertedValue;
1182 // First convert the value from primitiveUnitType() to canonical type.
1183 auto sourceFactor = conversionToCanonicalUnitsScaleFactor(sourceUnitType);
1184 if (!sourceFactor.has_value())
1185 return std::nullopt;
1186 convertedValue *= sourceFactor.value();
1188 // Now convert from canonical type to the target unitType.
1189 auto targetFactor = conversionToCanonicalUnitsScaleFactor(targetUnitType);
1190 if (!targetFactor.has_value())
1191 return std::nullopt;
1192 convertedValue /= targetFactor.value();
1194 return convertedValue;
1197 String CSSPrimitiveValue::stringValue() const
1199 switch (primitiveUnitType()) {
1200 case CSSUnitType::CSS_STRING:
1201 case CSSUnitType::CustomIdent:
1202 case CSSUnitType::CSS_ATTR:
1203 case CSSUnitType::CSS_URI:
1204 return m_value.string;
1205 case CSSUnitType::CSS_FONT_FAMILY:
1206 return m_value.fontFamily->familyName;
1207 case CSSUnitType::CSS_VALUE_ID:
1208 return valueName(m_value.valueID);
1209 case CSSUnitType::CSS_PROPERTY_ID:
1210 return propertyName(m_value.propertyID);
1211 default:
1212 return String();
1216 NEVER_INLINE String CSSPrimitiveValue::formatInfiniteOrNanValue(StringView suffix) const
1218 if (m_value.num == std::numeric_limits<double>::infinity())
1219 return makeString("infinity", suffix.isEmpty() ? "" : " * 1" , suffix);
1220 if (m_value.num == -std::numeric_limits<double>::infinity())
1221 return makeString("-infinity", suffix.isEmpty() ? "" : " * 1", suffix);
1222 if (std::isnan(m_value.num))
1223 return makeString(m_value.num, suffix.isEmpty() ? "" : " * 1", suffix);
1224 ASSERT_NOT_REACHED();
1225 return emptyString();
1228 NEVER_INLINE String CSSPrimitiveValue::formatNumberValue(StringView suffix) const
1230 if (std::isnan(m_value.num) || std::isinf(m_value.num))
1231 return formatInfiniteOrNanValue(suffix);
1232 return makeString(FormattedCSSNumber::create(m_value.num), suffix);
1235 NEVER_INLINE String CSSPrimitiveValue::formatIntegerValue(StringView suffix) const
1237 if (std::isnan(m_value.num) || std::isinf(m_value.num))
1238 return formatInfiniteOrNanValue(suffix);
1239 return makeString(m_value.num, suffix);
1242 // FIXME: Should return const char*.
1243 String CSSPrimitiveValue::unitTypeString(CSSUnitType unitType)
1245 switch (unitType) {
1246 case CSSUnitType::CSS_PERCENTAGE: return "%"_s;
1247 case CSSUnitType::CSS_EMS: return "em"_s;
1248 case CSSUnitType::CSS_EXS: return "ex"_s;
1249 case CSSUnitType::CSS_PX: return "px"_s;
1250 case CSSUnitType::CSS_CM: return "cm"_s;
1251 case CSSUnitType::CSS_MM: return "mm"_s;
1252 case CSSUnitType::CSS_IN: return "in"_s;
1253 case CSSUnitType::CSS_PT: return "pt"_s;
1254 case CSSUnitType::CSS_PC: return "pc"_s;
1255 case CSSUnitType::CSS_DEG: return "deg"_s;
1256 case CSSUnitType::CSS_RAD: return "rad"_s;
1257 case CSSUnitType::CSS_GRAD: return "grad"_s;
1258 case CSSUnitType::CSS_MS: return "ms"_s;
1259 case CSSUnitType::CSS_S: return "s"_s;
1260 case CSSUnitType::CSS_HZ: return "hz"_s;
1261 case CSSUnitType::CSS_KHZ: return "khz"_s;
1262 case CSSUnitType::CSS_VW: return "vw"_s;
1263 case CSSUnitType::CSS_VH: return "vh"_s;
1264 case CSSUnitType::CSS_VMIN: return "vmin"_s;
1265 case CSSUnitType::CSS_VMAX: return "vmax"_s;
1266 case CSSUnitType::CSS_VB: return "vb"_s;
1267 case CSSUnitType::CSS_VI: return "vi"_s;
1268 case CSSUnitType::CSS_SVW: return "svw"_s;
1269 case CSSUnitType::CSS_SVH: return "svh"_s;
1270 case CSSUnitType::CSS_SVMIN: return "svmin"_s;
1271 case CSSUnitType::CSS_SVMAX: return "svmax"_s;
1272 case CSSUnitType::CSS_SVB: return "svb"_s;
1273 case CSSUnitType::CSS_SVI: return "svi"_s;
1274 case CSSUnitType::CSS_LVW: return "lvw"_s;
1275 case CSSUnitType::CSS_LVH: return "lvh"_s;
1276 case CSSUnitType::CSS_LVMIN: return "lvmin"_s;
1277 case CSSUnitType::CSS_LVMAX: return "lvmax"_s;
1278 case CSSUnitType::CSS_LVB: return "lvb"_s;
1279 case CSSUnitType::CSS_LVI: return "lvi"_s;
1280 case CSSUnitType::CSS_DVW: return "dvw"_s;
1281 case CSSUnitType::CSS_DVH: return "dvh"_s;
1282 case CSSUnitType::CSS_DVMIN: return "dvmin"_s;
1283 case CSSUnitType::CSS_DVMAX: return "dvmax"_s;
1284 case CSSUnitType::CSS_DVB: return "dvb"_s;
1285 case CSSUnitType::CSS_DVI: return "dvi"_s;
1286 case CSSUnitType::CSS_DPPX: return "dppx"_s;
1287 case CSSUnitType::CSS_X: return "x"_s;
1288 case CSSUnitType::CSS_DPI: return "dpi"_s;
1289 case CSSUnitType::CSS_DPCM: return "dpcm"_s;
1290 case CSSUnitType::CSS_FR: return "fr"_s;
1291 case CSSUnitType::CSS_Q: return "q"_s;
1292 case CSSUnitType::CSS_LHS: return "lh"_s;
1293 case CSSUnitType::CSS_RLHS: return "rlh"_s;
1294 case CSSUnitType::CSS_TURN: return "turn"_s;
1295 case CSSUnitType::CSS_REMS: return "rem"_s;
1296 case CSSUnitType::CSS_CHS: return "ch"_s;
1297 case CSSUnitType::CSS_IC: return "ic"_s;
1298 case CSSUnitType::CSS_CQW: return "cqw"_s;
1299 case CSSUnitType::CSS_CQH: return "cqh"_s;
1300 case CSSUnitType::CSS_CQI: return "cqi"_s;
1301 case CSSUnitType::CSS_CQB: return "cqb"_s;
1302 case CSSUnitType::CSS_CQMAX: return "cqmax"_s;
1303 case CSSUnitType::CSS_CQMIN: return "cqmin"_s;
1305 case CSSUnitType::CSS_UNKNOWN:
1306 case CSSUnitType::CSS_NUMBER:
1307 case CSSUnitType::CSS_INTEGER:
1308 case CSSUnitType::CSS_DIMENSION:
1309 case CSSUnitType::CSS_STRING:
1310 case CSSUnitType::CSS_URI:
1311 case CSSUnitType::CSS_IDENT:
1312 case CSSUnitType::CustomIdent:
1313 case CSSUnitType::CSS_ATTR:
1314 case CSSUnitType::CSS_COUNTER:
1315 case CSSUnitType::CSS_RECT:
1316 case CSSUnitType::CSS_RGBCOLOR:
1317 case CSSUnitType::CSS_PAIR:
1318 case CSSUnitType::CSS_UNICODE_RANGE:
1319 case CSSUnitType::CSS_COUNTER_NAME:
1320 case CSSUnitType::CSS_SHAPE:
1321 case CSSUnitType::CSS_QUAD:
1322 case CSSUnitType::CSS_CALC:
1323 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
1324 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
1325 case CSSUnitType::CSS_FONT_FAMILY:
1326 case CSSUnitType::CSS_PROPERTY_ID:
1327 case CSSUnitType::CSS_VALUE_ID:
1328 case CSSUnitType::CSS_QUIRKY_EMS:
1329 return emptyString();
1331 ASSERT_NOT_REACHED();
1332 return emptyString();
1335 ALWAYS_INLINE String CSSPrimitiveValue::formatNumberForCustomCSSText() const
1337 switch (primitiveUnitType()) {
1338 case CSSUnitType::CSS_UNKNOWN:
1339 return String();
1340 case CSSUnitType::CSS_NUMBER:
1341 return formatNumberValue("");
1342 case CSSUnitType::CSS_INTEGER:
1343 return formatIntegerValue("");
1344 case CSSUnitType::CSS_PERCENTAGE:
1345 return formatNumberValue("%");
1346 case CSSUnitType::CSS_EMS:
1347 case CSSUnitType::CSS_QUIRKY_EMS:
1348 return formatNumberValue("em");
1349 case CSSUnitType::CSS_EXS:
1350 return formatNumberValue("ex");
1351 case CSSUnitType::CSS_REMS:
1352 return formatNumberValue("rem");
1353 case CSSUnitType::CSS_CHS:
1354 return formatNumberValue("ch");
1355 case CSSUnitType::CSS_IC:
1356 return formatNumberValue("ic");
1357 case CSSUnitType::CSS_PX:
1358 return formatNumberValue("px");
1359 case CSSUnitType::CSS_CM:
1360 return formatNumberValue("cm");
1361 case CSSUnitType::CSS_DPPX:
1362 return formatNumberValue("dppx");
1363 case CSSUnitType::CSS_X:
1364 return formatNumberValue("x");
1365 case CSSUnitType::CSS_DPI:
1366 return formatNumberValue("dpi");
1367 case CSSUnitType::CSS_DPCM:
1368 return formatNumberValue("dpcm");
1369 case CSSUnitType::CSS_MM:
1370 return formatNumberValue("mm");
1371 case CSSUnitType::CSS_IN:
1372 return formatNumberValue("in");
1373 case CSSUnitType::CSS_PT:
1374 return formatNumberValue("pt");
1375 case CSSUnitType::CSS_PC:
1376 return formatNumberValue("pc");
1377 case CSSUnitType::CSS_DEG:
1378 return formatNumberValue("deg");
1379 case CSSUnitType::CSS_RAD:
1380 return formatNumberValue("rad");
1381 case CSSUnitType::CSS_GRAD:
1382 return formatNumberValue("grad");
1383 case CSSUnitType::CSS_MS:
1384 return formatNumberValue("ms");
1385 case CSSUnitType::CSS_S:
1386 return formatNumberValue("s");
1387 case CSSUnitType::CSS_HZ:
1388 return formatNumberValue("hz");
1389 case CSSUnitType::CSS_KHZ:
1390 return formatNumberValue("khz");
1391 case CSSUnitType::CSS_TURN:
1392 return formatNumberValue("turn");
1393 case CSSUnitType::CSS_FR:
1394 return formatNumberValue("fr");
1395 case CSSUnitType::CSS_Q:
1396 return formatNumberValue("q");
1397 case CSSUnitType::CSS_LHS:
1398 return formatNumberValue("lh");
1399 case CSSUnitType::CSS_RLHS:
1400 return formatNumberValue("rlh");
1401 case CSSUnitType::CSS_CQW:
1402 return formatNumberValue("cqw");
1403 case CSSUnitType::CSS_CQH:
1404 return formatNumberValue("cqh");
1405 case CSSUnitType::CSS_CQI:
1406 return formatNumberValue("cqi");
1407 case CSSUnitType::CSS_CQB:
1408 return formatNumberValue("cqb");
1409 case CSSUnitType::CSS_CQMAX:
1410 return formatNumberValue("cqmax");
1411 case CSSUnitType::CSS_CQMIN:
1412 return formatNumberValue("cqmin");
1413 case CSSUnitType::CSS_DIMENSION:
1414 // FIXME: This isn't correct.
1415 return formatNumberValue("");
1416 case CSSUnitType::CSS_STRING:
1417 return serializeString(m_value.string);
1418 case CSSUnitType::CustomIdent: {
1419 StringBuilder builder;
1420 serializeIdentifier(m_value.string, builder);
1421 return builder.toString();
1423 case CSSUnitType::CSS_FONT_FAMILY:
1424 return serializeFontFamily(m_value.fontFamily->familyName);
1425 case CSSUnitType::CSS_URI:
1426 return serializeURL(m_value.string);
1427 case CSSUnitType::CSS_VALUE_ID:
1428 return valueName(m_value.valueID);
1429 case CSSUnitType::CSS_PROPERTY_ID:
1430 return propertyName(m_value.propertyID);
1431 case CSSUnitType::CSS_ATTR:
1432 return "attr(" + String(m_value.string) + ')';
1433 case CSSUnitType::CSS_COUNTER_NAME:
1434 return "counter(" + String(m_value.string) + ')';
1435 case CSSUnitType::CSS_COUNTER: {
1436 StringBuilder result;
1437 auto separator = m_value.counter->separator();
1438 auto listStyle = m_value.counter->listStyle();
1439 result.append(separator.isEmpty() ? "counter(" : "counters(", m_value.counter->identifier(), separator.isEmpty() ? "" : ", ");
1440 if (!separator.isEmpty())
1441 serializeString(separator, result);
1442 if (!(listStyle.isEmpty() || listStyle == "decimal"))
1443 result.append(", ", listStyle);
1444 result.append(')');
1445 return result.toString();
1447 case CSSUnitType::CSS_RECT:
1448 return rectValue()->cssText();
1449 case CSSUnitType::CSS_QUAD:
1450 return quadValue()->cssText();
1451 case CSSUnitType::CSS_RGBCOLOR:
1452 return serializationForCSS(color());
1453 case CSSUnitType::CSS_PAIR:
1454 return pairValue()->cssText();
1455 case CSSUnitType::CSS_CALC:
1456 if (!m_value.calc)
1457 break;
1458 return m_value.calc->cssText();
1459 case CSSUnitType::CSS_SHAPE:
1460 return m_value.shape->cssText();
1461 case CSSUnitType::CSS_VW:
1462 return formatNumberValue("vw");
1463 case CSSUnitType::CSS_VH:
1464 return formatNumberValue("vh");
1465 case CSSUnitType::CSS_VMIN:
1466 return formatNumberValue("vmin");
1467 case CSSUnitType::CSS_VMAX:
1468 return formatNumberValue("vmax");
1469 case CSSUnitType::CSS_VB:
1470 return formatNumberValue("vb");
1471 case CSSUnitType::CSS_VI:
1472 return formatNumberValue("vi");
1473 case CSSUnitType::CSS_SVW:
1474 return formatNumberValue("svw");
1475 case CSSUnitType::CSS_SVH:
1476 return formatNumberValue("svh");
1477 case CSSUnitType::CSS_SVMIN:
1478 return formatNumberValue("svmin");
1479 case CSSUnitType::CSS_SVMAX:
1480 return formatNumberValue("svmax");
1481 case CSSUnitType::CSS_SVB:
1482 return formatNumberValue("svb");
1483 case CSSUnitType::CSS_SVI:
1484 return formatNumberValue("svi");
1485 case CSSUnitType::CSS_LVW:
1486 return formatNumberValue("lvw");
1487 case CSSUnitType::CSS_LVH:
1488 return formatNumberValue("lvh");
1489 case CSSUnitType::CSS_LVMIN:
1490 return formatNumberValue("lvmin");
1491 case CSSUnitType::CSS_LVMAX:
1492 return formatNumberValue("lvmax");
1493 case CSSUnitType::CSS_LVB:
1494 return formatNumberValue("lvb");
1495 case CSSUnitType::CSS_LVI:
1496 return formatNumberValue("lvi");
1497 case CSSUnitType::CSS_DVW:
1498 return formatNumberValue("dvw");
1499 case CSSUnitType::CSS_DVH:
1500 return formatNumberValue("dvh");
1501 case CSSUnitType::CSS_DVMIN:
1502 return formatNumberValue("dvmin");
1503 case CSSUnitType::CSS_DVMAX:
1504 return formatNumberValue("dvmax");
1505 case CSSUnitType::CSS_DVB:
1506 return formatNumberValue("dvb");
1507 case CSSUnitType::CSS_DVI:
1508 return formatNumberValue("dvi");
1509 case CSSUnitType::CSS_IDENT:
1510 case CSSUnitType::CSS_UNICODE_RANGE:
1511 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
1512 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
1513 ASSERT_NOT_REACHED();
1515 return String();
1518 String CSSPrimitiveValue::customCSSText() const
1520 // FIXME: return the original value instead of a generated one (e.g. color
1521 // name if it was specified) - check what spec says about this
1523 CSSTextCache& cssTextCache = WebCore::cssTextCache();
1525 if (m_hasCachedCSSText) {
1526 ASSERT(cssTextCache.contains(this));
1527 return cssTextCache.get(this);
1530 String text = formatNumberForCustomCSSText();
1532 ASSERT(!cssTextCache.contains(this));
1533 m_hasCachedCSSText = true;
1534 cssTextCache.set(this, text);
1535 return text;
1538 bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
1540 if (primitiveUnitType() != other.primitiveUnitType())
1541 return false;
1543 switch (primitiveUnitType()) {
1544 case CSSUnitType::CSS_UNKNOWN:
1545 return false;
1546 case CSSUnitType::CSS_NUMBER:
1547 case CSSUnitType::CSS_INTEGER:
1548 case CSSUnitType::CSS_PERCENTAGE:
1549 case CSSUnitType::CSS_EMS:
1550 case CSSUnitType::CSS_QUIRKY_EMS:
1551 case CSSUnitType::CSS_EXS:
1552 case CSSUnitType::CSS_REMS:
1553 case CSSUnitType::CSS_CHS:
1554 case CSSUnitType::CSS_IC:
1555 case CSSUnitType::CSS_PX:
1556 case CSSUnitType::CSS_CM:
1557 case CSSUnitType::CSS_DPPX:
1558 case CSSUnitType::CSS_X:
1559 case CSSUnitType::CSS_DPI:
1560 case CSSUnitType::CSS_DPCM:
1561 case CSSUnitType::CSS_MM:
1562 case CSSUnitType::CSS_IN:
1563 case CSSUnitType::CSS_PT:
1564 case CSSUnitType::CSS_PC:
1565 case CSSUnitType::CSS_DEG:
1566 case CSSUnitType::CSS_RAD:
1567 case CSSUnitType::CSS_GRAD:
1568 case CSSUnitType::CSS_MS:
1569 case CSSUnitType::CSS_S:
1570 case CSSUnitType::CSS_HZ:
1571 case CSSUnitType::CSS_KHZ:
1572 case CSSUnitType::CSS_TURN:
1573 case CSSUnitType::CSS_VW:
1574 case CSSUnitType::CSS_VH:
1575 case CSSUnitType::CSS_VMIN:
1576 case CSSUnitType::CSS_VMAX:
1577 case CSSUnitType::CSS_VB:
1578 case CSSUnitType::CSS_VI:
1579 case CSSUnitType::CSS_SVW:
1580 case CSSUnitType::CSS_SVH:
1581 case CSSUnitType::CSS_SVMIN:
1582 case CSSUnitType::CSS_SVMAX:
1583 case CSSUnitType::CSS_SVB:
1584 case CSSUnitType::CSS_SVI:
1585 case CSSUnitType::CSS_LVW:
1586 case CSSUnitType::CSS_LVH:
1587 case CSSUnitType::CSS_LVMIN:
1588 case CSSUnitType::CSS_LVMAX:
1589 case CSSUnitType::CSS_LVB:
1590 case CSSUnitType::CSS_LVI:
1591 case CSSUnitType::CSS_DVW:
1592 case CSSUnitType::CSS_DVH:
1593 case CSSUnitType::CSS_DVMIN:
1594 case CSSUnitType::CSS_DVMAX:
1595 case CSSUnitType::CSS_DVB:
1596 case CSSUnitType::CSS_DVI:
1597 case CSSUnitType::CSS_FR:
1598 case CSSUnitType::CSS_Q:
1599 case CSSUnitType::CSS_LHS:
1600 case CSSUnitType::CSS_RLHS:
1601 case CSSUnitType::CSS_DIMENSION:
1602 case CSSUnitType::CSS_CQW:
1603 case CSSUnitType::CSS_CQH:
1604 case CSSUnitType::CSS_CQI:
1605 case CSSUnitType::CSS_CQB:
1606 case CSSUnitType::CSS_CQMIN:
1607 case CSSUnitType::CSS_CQMAX:
1608 return m_value.num == other.m_value.num;
1609 case CSSUnitType::CSS_PROPERTY_ID:
1610 return propertyName(m_value.propertyID) == propertyName(other.m_value.propertyID);
1611 case CSSUnitType::CSS_VALUE_ID:
1612 return valueName(m_value.valueID) == valueName(other.m_value.valueID);
1613 case CSSUnitType::CSS_STRING:
1614 case CSSUnitType::CustomIdent:
1615 case CSSUnitType::CSS_URI:
1616 case CSSUnitType::CSS_ATTR:
1617 case CSSUnitType::CSS_COUNTER_NAME:
1618 return equal(m_value.string, other.m_value.string);
1619 case CSSUnitType::CSS_COUNTER:
1620 return m_value.counter && other.m_value.counter && m_value.counter->equals(*other.m_value.counter);
1621 case CSSUnitType::CSS_RECT:
1622 return m_value.rect && other.m_value.rect && m_value.rect->equals(*other.m_value.rect);
1623 case CSSUnitType::CSS_QUAD:
1624 return m_value.quad && other.m_value.quad && m_value.quad->equals(*other.m_value.quad);
1625 case CSSUnitType::CSS_RGBCOLOR:
1626 return color() == other.color();
1627 case CSSUnitType::CSS_PAIR:
1628 return m_value.pair && other.m_value.pair && m_value.pair->equals(*other.m_value.pair);
1629 case CSSUnitType::CSS_CALC:
1630 return m_value.calc && other.m_value.calc && m_value.calc->equals(*other.m_value.calc);
1631 case CSSUnitType::CSS_SHAPE:
1632 return m_value.shape && other.m_value.shape && m_value.shape->equals(*other.m_value.shape);
1633 case CSSUnitType::CSS_FONT_FAMILY:
1634 return fontFamily() == other.fontFamily();
1635 case CSSUnitType::CSS_IDENT:
1636 case CSSUnitType::CSS_UNICODE_RANGE:
1637 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_NUMBER:
1638 case CSSUnitType::CSS_CALC_PERCENTAGE_WITH_LENGTH:
1639 // FIXME: seems like these should be handled.
1640 ASSERT_NOT_REACHED();
1641 break;
1643 return false;
1646 Ref<DeprecatedCSSOMPrimitiveValue> CSSPrimitiveValue::createDeprecatedCSSOMPrimitiveWrapper(CSSStyleDeclaration& styleDeclaration) const
1648 return DeprecatedCSSOMPrimitiveValue::create(*this, styleDeclaration);
1651 // https://drafts.css-houdini.org/css-properties-values-api/#dependency-cycles
1652 void CSSPrimitiveValue::collectDirectComputationalDependencies(HashSet<CSSPropertyID>& values) const
1654 switch (primitiveUnitType()) {
1655 case CSSUnitType::CSS_EMS:
1656 case CSSUnitType::CSS_QUIRKY_EMS:
1657 case CSSUnitType::CSS_EXS:
1658 case CSSUnitType::CSS_CHS:
1659 case CSSUnitType::CSS_IC:
1660 values.add(CSSPropertyFontSize);
1661 break;
1662 case CSSUnitType::CSS_LHS:
1663 values.add(CSSPropertyFontSize);
1664 values.add(CSSPropertyLineHeight);
1665 break;
1666 case CSSUnitType::CSS_CALC:
1667 m_value.calc->collectDirectComputationalDependencies(values);
1668 break;
1669 default:
1670 break;
1674 void CSSPrimitiveValue::collectDirectRootComputationalDependencies(HashSet<CSSPropertyID>& values) const
1676 switch (primitiveUnitType()) {
1677 case CSSUnitType::CSS_REMS:
1678 values.add(CSSPropertyFontSize);
1679 break;
1680 case CSSUnitType::CSS_RLHS:
1681 values.add(CSSPropertyFontSize);
1682 values.add(CSSPropertyLineHeight);
1683 break;
1684 case CSSUnitType::CSS_CALC:
1685 m_value.calc->collectDirectRootComputationalDependencies(values);
1686 break;
1687 default:
1688 break;
1692 bool CSSPrimitiveValue::isCSSWideKeyword() const
1694 return WebCore::isCSSWideKeyword(valueID());
1697 } // namespace WebCore