REGRESSION(r244635): [GTK] Wrong background color used in non-dark mode
[WebKit-https.git] / Source / WebCore / css / CSSPrimitiveValueMappings.h
1 /*
2  * Copyright (C) 2007 Alexey Proskuryakov <ap@nypop.com>.
3  * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
4  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
5  * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com>
6  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #pragma once
31
32 #include "CSSCalculationValue.h"
33 #include "CSSFontFamily.h"
34 #include "CSSPrimitiveValue.h"
35 #include "CSSReflectionDirection.h"
36 #include "CSSToLengthConversionData.h"
37 #include "CSSValueKeywords.h"
38 #include "GraphicsTypes.h"
39 #include "Length.h"
40 #include "LineClampValue.h"
41 #include "RenderStyleConstants.h"
42 #include "SVGRenderStyleDefs.h"
43 #include "TextFlags.h"
44 #include "ThemeTypes.h"
45 #include "TouchAction.h"
46 #include "UnicodeBidi.h"
47 #include "WritingMode.h"
48 #include <wtf/MathExtras.h>
49 #include <wtf/OptionSet.h>
50
51 #if ENABLE(CSS_IMAGE_ORIENTATION)
52 #include "ImageOrientation.h"
53 #endif
54
55 namespace WebCore {
56
57 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(short i)
58     : CSSValue(PrimitiveClass)
59 {
60     m_primitiveUnitType = CSS_NUMBER;
61     m_value.num = static_cast<double>(i);
62 }
63
64 template<> inline CSSPrimitiveValue::operator short() const
65 {
66     if (m_primitiveUnitType == CSS_NUMBER)
67         return clampTo<short>(m_value.num);
68
69     ASSERT_NOT_REACHED();
70     return 0;
71 }
72
73 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(unsigned short i)
74     : CSSValue(PrimitiveClass)
75 {
76     m_primitiveUnitType = CSS_NUMBER;
77     m_value.num = static_cast<double>(i);
78 }
79
80 template<> inline CSSPrimitiveValue::operator unsigned short() const
81 {
82     if (primitiveType() == CSS_NUMBER)
83         return value<unsigned short>();
84
85     ASSERT_NOT_REACHED();
86     return 0;
87 }
88
89 template<> inline CSSPrimitiveValue::operator int() const
90 {
91     if (primitiveType() == CSS_NUMBER)
92         return value<int>();
93
94     ASSERT_NOT_REACHED();
95     return 0;
96 }
97
98 template<> inline CSSPrimitiveValue::operator unsigned() const
99 {
100     if (primitiveType() == CSS_NUMBER)
101         return value<unsigned>();
102
103     ASSERT_NOT_REACHED();
104     return 0;
105 }
106
107
108 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(float i)
109     : CSSValue(PrimitiveClass)
110 {
111     m_primitiveUnitType = CSS_NUMBER;
112     m_value.num = static_cast<double>(i);
113 }
114
115 template<> inline CSSPrimitiveValue::operator float() const
116 {
117     if (primitiveType() == CSS_NUMBER)
118         return value<float>();
119
120     ASSERT_NOT_REACHED();
121     return 0.0f;
122 }
123
124 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineClampValue i)
125     : CSSValue(PrimitiveClass)
126 {
127     m_primitiveUnitType = i.isPercentage() ? CSS_PERCENTAGE : CSS_NUMBER;
128     m_value.num = static_cast<double>(i.value());
129 }
130
131 template<> inline CSSPrimitiveValue::operator LineClampValue() const
132 {
133     if (primitiveType() == CSS_NUMBER)
134         return LineClampValue(value<int>(), LineClamp::LineCount);
135
136     if (primitiveType() == CSS_PERCENTAGE)
137         return LineClampValue(value<int>(), LineClamp::Percentage);
138
139     ASSERT_NOT_REACHED();
140     return LineClampValue();
141 }
142
143 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CSSReflectionDirection e)
144     : CSSValue(PrimitiveClass)
145 {
146     m_primitiveUnitType = CSS_VALUE_ID;
147     switch (e) {
148     case ReflectionAbove:
149         m_value.valueID = CSSValueAbove;
150         break;
151     case ReflectionBelow:
152         m_value.valueID = CSSValueBelow;
153         break;
154     case ReflectionLeft:
155         m_value.valueID = CSSValueLeft;
156         break;
157     case ReflectionRight:
158         m_value.valueID = CSSValueRight;
159     }
160 }
161
162 template<> inline CSSPrimitiveValue::operator CSSReflectionDirection() const
163 {
164     ASSERT(isValueID());
165
166     switch (m_value.valueID) {
167     case CSSValueAbove:
168         return ReflectionAbove;
169     case CSSValueBelow:
170         return ReflectionBelow;
171     case CSSValueLeft:
172         return ReflectionLeft;
173     case CSSValueRight:
174         return ReflectionRight;
175     default:
176         break;
177     }
178
179     ASSERT_NOT_REACHED();
180     return ReflectionBelow;
181 }
182
183 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnFill columnFill)
184     : CSSValue(PrimitiveClass)
185 {
186     m_primitiveUnitType = CSS_VALUE_ID;
187     switch (columnFill) {
188     case ColumnFill::Auto:
189         m_value.valueID = CSSValueAuto;
190         break;
191     case ColumnFill::Balance:
192         m_value.valueID = CSSValueBalance;
193         break;
194     }
195 }
196
197 template<> inline CSSPrimitiveValue::operator ColumnFill() const
198 {
199     if (m_primitiveUnitType == CSS_VALUE_ID) {
200         if (m_value.valueID == CSSValueBalance)
201             return ColumnFill::Balance;
202         if (m_value.valueID == CSSValueAuto)
203             return ColumnFill::Auto;
204     }
205     ASSERT_NOT_REACHED();
206     return ColumnFill::Balance;
207 }
208
209 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnSpan columnSpan)
210     : CSSValue(PrimitiveClass)
211 {
212     m_primitiveUnitType = CSS_VALUE_ID;
213     switch (columnSpan) {
214     case ColumnSpan::All:
215         m_value.valueID = CSSValueAll;
216         break;
217     case ColumnSpan::None:
218         m_value.valueID = CSSValueNone;
219         break;
220     }
221 }
222
223 template<> inline CSSPrimitiveValue::operator ColumnSpan() const
224 {
225     // Map 1 to none for compatibility reasons.
226     if (m_primitiveUnitType == CSS_NUMBER && m_value.num == 1)
227         return ColumnSpan::None;
228
229     ASSERT(isValueID());
230
231     switch (m_value.valueID) {
232     case CSSValueAll:
233         return ColumnSpan::All;
234     case CSSValueNone:
235         return ColumnSpan::None;
236     default:
237         break;
238     }
239
240     ASSERT_NOT_REACHED();
241     return ColumnSpan::None;
242 }
243
244
245 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(PrintColorAdjust value)
246     : CSSValue(PrimitiveClass)
247 {
248     m_primitiveUnitType = CSS_VALUE_ID;
249     switch (value) {
250     case PrintColorAdjust::Exact:
251         m_value.valueID = CSSValueExact;
252         break;
253     case PrintColorAdjust::Economy:
254         m_value.valueID = CSSValueEconomy;
255         break;
256     }
257 }
258
259 template<> inline CSSPrimitiveValue::operator PrintColorAdjust() const
260 {
261     ASSERT(isValueID());
262
263     switch (m_value.valueID) {
264     case CSSValueEconomy:
265         return PrintColorAdjust::Economy;
266     case CSSValueExact:
267         return PrintColorAdjust::Exact;
268     default:
269         break;
270     }
271
272     ASSERT_NOT_REACHED();
273     return PrintColorAdjust::Economy;
274 }
275
276
277 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BorderStyle e)
278     : CSSValue(PrimitiveClass)
279 {
280     m_primitiveUnitType = CSS_VALUE_ID;
281     switch (e) {
282     case BorderStyle::None:
283         m_value.valueID = CSSValueNone;
284         break;
285     case BorderStyle::Hidden:
286         m_value.valueID = CSSValueHidden;
287         break;
288     case BorderStyle::Inset:
289         m_value.valueID = CSSValueInset;
290         break;
291     case BorderStyle::Groove:
292         m_value.valueID = CSSValueGroove;
293         break;
294     case BorderStyle::Ridge:
295         m_value.valueID = CSSValueRidge;
296         break;
297     case BorderStyle::Outset:
298         m_value.valueID = CSSValueOutset;
299         break;
300     case BorderStyle::Dotted:
301         m_value.valueID = CSSValueDotted;
302         break;
303     case BorderStyle::Dashed:
304         m_value.valueID = CSSValueDashed;
305         break;
306     case BorderStyle::Solid:
307         m_value.valueID = CSSValueSolid;
308         break;
309     case BorderStyle::Double:
310         m_value.valueID = CSSValueDouble;
311         break;
312     }
313 }
314
315 template<> inline CSSPrimitiveValue::operator BorderStyle() const
316 {
317     ASSERT(isValueID());
318
319     if (m_value.valueID == CSSValueAuto) // Valid for CSS outline-style
320         return BorderStyle::Dotted;
321     return static_cast<BorderStyle>(m_value.valueID - CSSValueNone);
322 }
323
324 template<> inline CSSPrimitiveValue::operator OutlineIsAuto() const
325 {
326     ASSERT(isValueID());
327
328     if (m_value.valueID == CSSValueAuto)
329         return OutlineIsAuto::On;
330     return OutlineIsAuto::Off;
331 }
332
333 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CompositeOperator e)
334     : CSSValue(PrimitiveClass)
335 {
336     m_primitiveUnitType = CSS_VALUE_ID;
337     switch (e) {
338     case CompositeClear:
339         m_value.valueID = CSSValueClear;
340         break;
341     case CompositeCopy:
342         m_value.valueID = CSSValueCopy;
343         break;
344     case CompositeSourceOver:
345         m_value.valueID = CSSValueSourceOver;
346         break;
347     case CompositeSourceIn:
348         m_value.valueID = CSSValueSourceIn;
349         break;
350     case CompositeSourceOut:
351         m_value.valueID = CSSValueSourceOut;
352         break;
353     case CompositeSourceAtop:
354         m_value.valueID = CSSValueSourceAtop;
355         break;
356     case CompositeDestinationOver:
357         m_value.valueID = CSSValueDestinationOver;
358         break;
359     case CompositeDestinationIn:
360         m_value.valueID = CSSValueDestinationIn;
361         break;
362     case CompositeDestinationOut:
363         m_value.valueID = CSSValueDestinationOut;
364         break;
365     case CompositeDestinationAtop:
366         m_value.valueID = CSSValueDestinationAtop;
367         break;
368     case CompositeXOR:
369         m_value.valueID = CSSValueXor;
370         break;
371     case CompositePlusDarker:
372         m_value.valueID = CSSValuePlusDarker;
373         break;
374     case CompositePlusLighter:
375         m_value.valueID = CSSValuePlusLighter;
376         break;
377     case CompositeDifference:
378         ASSERT_NOT_REACHED();
379         break;
380     }
381 }
382
383 template<> inline CSSPrimitiveValue::operator CompositeOperator() const
384 {
385     ASSERT(isValueID());
386
387     switch (m_value.valueID) {
388     case CSSValueClear:
389         return CompositeClear;
390     case CSSValueCopy:
391         return CompositeCopy;
392     case CSSValueSourceOver:
393         return CompositeSourceOver;
394     case CSSValueSourceIn:
395         return CompositeSourceIn;
396     case CSSValueSourceOut:
397         return CompositeSourceOut;
398     case CSSValueSourceAtop:
399         return CompositeSourceAtop;
400     case CSSValueDestinationOver:
401         return CompositeDestinationOver;
402     case CSSValueDestinationIn:
403         return CompositeDestinationIn;
404     case CSSValueDestinationOut:
405         return CompositeDestinationOut;
406     case CSSValueDestinationAtop:
407         return CompositeDestinationAtop;
408     case CSSValueXor:
409         return CompositeXOR;
410     case CSSValuePlusDarker:
411         return CompositePlusDarker;
412     case CSSValuePlusLighter:
413         return CompositePlusLighter;
414     default:
415         break;
416     }
417
418     ASSERT_NOT_REACHED();
419     return CompositeClear;
420 }
421
422 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e)
423     : CSSValue(PrimitiveClass)
424 {
425     m_primitiveUnitType = CSS_VALUE_ID;
426     switch (e) {
427     case NoControlPart:
428         m_value.valueID = CSSValueNone;
429         break;
430     case CheckboxPart:
431         m_value.valueID = CSSValueCheckbox;
432         break;
433     case RadioPart:
434         m_value.valueID = CSSValueRadio;
435         break;
436     case PushButtonPart:
437         m_value.valueID = CSSValuePushButton;
438         break;
439     case SquareButtonPart:
440         m_value.valueID = CSSValueSquareButton;
441         break;
442     case ButtonPart:
443         m_value.valueID = CSSValueButton;
444         break;
445     case ButtonBevelPart:
446         m_value.valueID = CSSValueButtonBevel;
447         break;
448     case DefaultButtonPart:
449         m_value.valueID = CSSValueDefaultButton;
450         break;
451     case InnerSpinButtonPart:
452         m_value.valueID = CSSValueInnerSpinButton;
453         break;
454     case ListboxPart:
455         m_value.valueID = CSSValueListbox;
456         break;
457     case ListItemPart:
458         m_value.valueID = CSSValueListitem;
459         break;
460     case MediaEnterFullscreenButtonPart:
461         m_value.valueID = CSSValueMediaEnterFullscreenButton;
462         break;
463     case MediaExitFullscreenButtonPart:
464         m_value.valueID = CSSValueMediaExitFullscreenButton;
465         break;
466     case MediaPlayButtonPart:
467         m_value.valueID = CSSValueMediaPlayButton;
468         break;
469     case MediaOverlayPlayButtonPart:
470         m_value.valueID = CSSValueMediaOverlayPlayButton;
471         break;
472     case MediaMuteButtonPart:
473         m_value.valueID = CSSValueMediaMuteButton;
474         break;
475     case MediaSeekBackButtonPart:
476         m_value.valueID = CSSValueMediaSeekBackButton;
477         break;
478     case MediaSeekForwardButtonPart:
479         m_value.valueID = CSSValueMediaSeekForwardButton;
480         break;
481     case MediaRewindButtonPart:
482         m_value.valueID = CSSValueMediaRewindButton;
483         break;
484     case MediaReturnToRealtimeButtonPart:
485         m_value.valueID = CSSValueMediaReturnToRealtimeButton;
486         break;
487     case MediaToggleClosedCaptionsButtonPart:
488         m_value.valueID = CSSValueMediaToggleClosedCaptionsButton;
489         break;
490     case MediaSliderPart:
491         m_value.valueID = CSSValueMediaSlider;
492         break;
493     case MediaSliderThumbPart:
494         m_value.valueID = CSSValueMediaSliderthumb;
495         break;
496     case MediaVolumeSliderContainerPart:
497         m_value.valueID = CSSValueMediaVolumeSliderContainer;
498         break;
499     case MediaVolumeSliderPart:
500         m_value.valueID = CSSValueMediaVolumeSlider;
501         break;
502     case MediaVolumeSliderMuteButtonPart:
503         m_value.valueID = CSSValueMediaVolumeSliderMuteButton;
504         break;
505     case MediaVolumeSliderThumbPart:
506         m_value.valueID = CSSValueMediaVolumeSliderthumb;
507         break;
508     case MediaControlsBackgroundPart:
509         m_value.valueID = CSSValueMediaControlsBackground;
510         break;
511     case MediaControlsFullscreenBackgroundPart:
512         m_value.valueID = CSSValueMediaControlsFullscreenBackground;
513         break;
514     case MediaFullScreenVolumeSliderPart:
515         m_value.valueID = CSSValueMediaFullscreenVolumeSlider;
516         break;
517     case MediaFullScreenVolumeSliderThumbPart:
518         m_value.valueID = CSSValueMediaFullscreenVolumeSliderThumb;
519         break;
520     case MediaCurrentTimePart:
521         m_value.valueID = CSSValueMediaCurrentTimeDisplay;
522         break;
523     case MediaTimeRemainingPart:
524         m_value.valueID = CSSValueMediaTimeRemainingDisplay;
525         break;
526     case MediaControlsLightBarBackgroundPart:
527         m_value.valueID = CSSValueMediaControlsLightBarBackground;
528         break;
529     case MediaControlsDarkBarBackgroundPart:
530         m_value.valueID = CSSValueMediaControlsDarkBarBackground;
531         break;
532     case MenulistPart:
533         m_value.valueID = CSSValueMenulist;
534         break;
535     case MenulistButtonPart:
536         m_value.valueID = CSSValueMenulistButton;
537         break;
538     case MenulistTextPart:
539         m_value.valueID = CSSValueMenulistText;
540         break;
541     case MenulistTextFieldPart:
542         m_value.valueID = CSSValueMenulistTextfield;
543         break;
544     case MeterPart:
545         m_value.valueID = CSSValueMeter;
546         break;
547     case RelevancyLevelIndicatorPart:
548         m_value.valueID = CSSValueRelevancyLevelIndicator;
549         break;
550     case ContinuousCapacityLevelIndicatorPart:
551         m_value.valueID = CSSValueContinuousCapacityLevelIndicator;
552         break;
553     case DiscreteCapacityLevelIndicatorPart:
554         m_value.valueID = CSSValueDiscreteCapacityLevelIndicator;
555         break;
556     case RatingLevelIndicatorPart:
557         m_value.valueID = CSSValueRatingLevelIndicator;
558         break;
559     case ProgressBarPart:
560         m_value.valueID = CSSValueProgressBar;
561         break;
562     case ProgressBarValuePart:
563         m_value.valueID = CSSValueProgressBarValue;
564         break;
565     case SliderHorizontalPart:
566         m_value.valueID = CSSValueSliderHorizontal;
567         break;
568     case SliderVerticalPart:
569         m_value.valueID = CSSValueSliderVertical;
570         break;
571     case SliderThumbHorizontalPart:
572         m_value.valueID = CSSValueSliderthumbHorizontal;
573         break;
574     case SliderThumbVerticalPart:
575         m_value.valueID = CSSValueSliderthumbVertical;
576         break;
577     case CaretPart:
578         m_value.valueID = CSSValueCaret;
579         break;
580     case SearchFieldPart:
581         m_value.valueID = CSSValueSearchfield;
582         break;
583     case SearchFieldDecorationPart:
584         m_value.valueID = CSSValueSearchfieldDecoration;
585         break;
586     case SearchFieldResultsDecorationPart:
587         m_value.valueID = CSSValueSearchfieldResultsDecoration;
588         break;
589     case SearchFieldResultsButtonPart:
590         m_value.valueID = CSSValueSearchfieldResultsButton;
591         break;
592     case SearchFieldCancelButtonPart:
593         m_value.valueID = CSSValueSearchfieldCancelButton;
594         break;
595     case SnapshottedPluginOverlayPart:
596         m_value.valueID = CSSValueSnapshottedPluginOverlay;
597         break;
598     case TextFieldPart:
599         m_value.valueID = CSSValueTextfield;
600         break;
601     case TextAreaPart:
602         m_value.valueID = CSSValueTextarea;
603         break;
604     case CapsLockIndicatorPart:
605         m_value.valueID = CSSValueCapsLockIndicator;
606         break;
607 #if ENABLE(ATTACHMENT_ELEMENT)
608     case AttachmentPart:
609         m_value.valueID = CSSValueAttachment;
610         break;
611     case BorderlessAttachmentPart:
612         m_value.valueID = CSSValueBorderlessAttachment;
613         break;
614 #endif
615 #if ENABLE(SERVICE_CONTROLS)
616     case ImageControlsButtonPart:
617         m_value.valueID = CSSValueImageControlsButton;
618         break;
619 #endif
620 #if ENABLE(APPLE_PAY)
621     case ApplePayButtonPart:
622         m_value.valueID = CSSValueApplePayButton;
623         break;
624 #endif
625 #if ENABLE(INPUT_TYPE_COLOR)
626     case ColorWellPart:
627         m_value.valueID = CSSValueColorWell;
628         break;
629 #endif
630 #if ENABLE(DATALIST_ELEMENT)
631     case ListButtonPart:
632         m_value.valueID = CSSValueListButton;
633         break;
634 #endif
635     }
636 }
637
638 template<> inline CSSPrimitiveValue::operator ControlPart() const
639 {
640     ASSERT(isValueID());
641
642     if (m_value.valueID == CSSValueNone)
643         return NoControlPart;
644     return ControlPart(m_value.valueID - CSSValueCheckbox + 1);
645 }
646
647 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BackfaceVisibility e)
648     : CSSValue(PrimitiveClass)
649 {
650     m_primitiveUnitType = CSS_VALUE_ID;
651     switch (e) {
652     case BackfaceVisibility::Visible:
653         m_value.valueID = CSSValueVisible;
654         break;
655     case BackfaceVisibility::Hidden:
656         m_value.valueID = CSSValueHidden;
657         break;
658     }
659 }
660
661 template<> inline CSSPrimitiveValue::operator BackfaceVisibility() const
662 {
663     ASSERT(isValueID());
664
665     switch (m_value.valueID) {
666     case CSSValueVisible:
667         return BackfaceVisibility::Visible;
668     case CSSValueHidden:
669         return BackfaceVisibility::Hidden;
670     default:
671         break;
672     }
673
674     ASSERT_NOT_REACHED();
675     return BackfaceVisibility::Hidden;
676 }
677
678
679 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FillAttachment e)
680     : CSSValue(PrimitiveClass)
681 {
682     m_primitiveUnitType = CSS_VALUE_ID;
683     switch (e) {
684     case FillAttachment::ScrollBackground:
685         m_value.valueID = CSSValueScroll;
686         break;
687     case FillAttachment::LocalBackground:
688         m_value.valueID = CSSValueLocal;
689         break;
690     case FillAttachment::FixedBackground:
691         m_value.valueID = CSSValueFixed;
692         break;
693     }
694 }
695
696 template<> inline CSSPrimitiveValue::operator FillAttachment() const
697 {
698     ASSERT(isValueID());
699
700     switch (m_value.valueID) {
701     case CSSValueScroll:
702         return FillAttachment::ScrollBackground;
703     case CSSValueLocal:
704         return FillAttachment::LocalBackground;
705     case CSSValueFixed:
706         return FillAttachment::FixedBackground;
707     default:
708         break;
709     }
710
711     ASSERT_NOT_REACHED();
712     return FillAttachment::ScrollBackground;
713 }
714
715 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FillBox e)
716     : CSSValue(PrimitiveClass)
717 {
718     m_primitiveUnitType = CSS_VALUE_ID;
719     switch (e) {
720     case FillBox::Border:
721         m_value.valueID = CSSValueBorderBox;
722         break;
723     case FillBox::Padding:
724         m_value.valueID = CSSValuePaddingBox;
725         break;
726     case FillBox::Content:
727         m_value.valueID = CSSValueContentBox;
728         break;
729     case FillBox::Text:
730         m_value.valueID = CSSValueText;
731         break;
732     }
733 }
734
735 template<> inline CSSPrimitiveValue::operator FillBox() const
736 {
737     ASSERT(isValueID());
738
739     switch (m_value.valueID) {
740     case CSSValueBorder:
741     case CSSValueBorderBox:
742         return FillBox::Border;
743     case CSSValuePadding:
744     case CSSValuePaddingBox:
745         return FillBox::Padding;
746     case CSSValueContent:
747     case CSSValueContentBox:
748         return FillBox::Content;
749     case CSSValueText:
750     case CSSValueWebkitText:
751         return FillBox::Text;
752     default:
753         break;
754     }
755
756     ASSERT_NOT_REACHED();
757     return FillBox::Border;
758 }
759
760 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FillRepeat e)
761     : CSSValue(PrimitiveClass)
762 {
763     m_primitiveUnitType = CSS_VALUE_ID;
764     switch (e) {
765     case FillRepeat::Repeat:
766         m_value.valueID = CSSValueRepeat;
767         break;
768     case FillRepeat::NoRepeat:
769         m_value.valueID = CSSValueNoRepeat;
770         break;
771     case FillRepeat::Round:
772         m_value.valueID = CSSValueRound;
773         break;
774     case FillRepeat::Space:
775         m_value.valueID = CSSValueSpace;
776         break;
777     }
778 }
779
780 template<> inline CSSPrimitiveValue::operator FillRepeat() const
781 {
782     ASSERT(isValueID());
783
784     switch (m_value.valueID) {
785     case CSSValueRepeat:
786         return FillRepeat::Repeat;
787     case CSSValueNoRepeat:
788         return FillRepeat::NoRepeat;
789     case CSSValueRound:
790         return FillRepeat::Round;
791     case CSSValueSpace:
792         return FillRepeat::Space;
793     default:
794         break;
795     }
796
797     ASSERT_NOT_REACHED();
798     return FillRepeat::Repeat;
799 }
800
801 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxPack e)
802     : CSSValue(PrimitiveClass)
803 {
804     m_primitiveUnitType = CSS_VALUE_ID;
805     switch (e) {
806     case BoxPack::Start:
807         m_value.valueID = CSSValueStart;
808         break;
809     case BoxPack::Center:
810         m_value.valueID = CSSValueCenter;
811         break;
812     case BoxPack::End:
813         m_value.valueID = CSSValueEnd;
814         break;
815     case BoxPack::Justify:
816         m_value.valueID = CSSValueJustify;
817         break;
818     }
819 }
820
821 template<> inline CSSPrimitiveValue::operator BoxPack() const
822 {
823     ASSERT(isValueID());
824
825     switch (m_value.valueID) {
826     case CSSValueStart:
827         return BoxPack::Start;
828     case CSSValueEnd:
829         return BoxPack::End;
830     case CSSValueCenter:
831         return BoxPack::Center;
832     case CSSValueJustify:
833         return BoxPack::Justify;
834     default:
835         break;
836     }
837
838     ASSERT_NOT_REACHED();
839     return BoxPack::Justify;
840 }
841
842 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxAlignment e)
843     : CSSValue(PrimitiveClass)
844 {
845     m_primitiveUnitType = CSS_VALUE_ID;
846     switch (e) {
847     case BoxAlignment::Stretch:
848         m_value.valueID = CSSValueStretch;
849         break;
850     case BoxAlignment::Start:
851         m_value.valueID = CSSValueStart;
852         break;
853     case BoxAlignment::Center:
854         m_value.valueID = CSSValueCenter;
855         break;
856     case BoxAlignment::End:
857         m_value.valueID = CSSValueEnd;
858         break;
859     case BoxAlignment::Baseline:
860         m_value.valueID = CSSValueBaseline;
861         break;
862     }
863 }
864
865 template<> inline CSSPrimitiveValue::operator BoxAlignment() const
866 {
867     ASSERT(isValueID());
868
869     switch (m_value.valueID) {
870     case CSSValueStretch:
871         return BoxAlignment::Stretch;
872     case CSSValueStart:
873         return BoxAlignment::Start;
874     case CSSValueEnd:
875         return BoxAlignment::End;
876     case CSSValueCenter:
877         return BoxAlignment::Center;
878     case CSSValueBaseline:
879         return BoxAlignment::Baseline;
880     default:
881         break;
882     }
883
884     ASSERT_NOT_REACHED();
885     return BoxAlignment::Stretch;
886 }
887
888 #if ENABLE(CSS_BOX_DECORATION_BREAK)
889 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxDecorationBreak e)
890     : CSSValue(PrimitiveClass)
891 {
892     m_primitiveUnitType = CSS_VALUE_ID;
893     switch (e) {
894     case BoxDecorationBreak::Slice:
895         m_value.valueID = CSSValueSlice;
896         break;
897     case BoxDecorationBreak::Clone:
898         m_value.valueID = CSSValueClone;
899         break;
900     }
901 }
902
903 template<> inline CSSPrimitiveValue::operator BoxDecorationBreak() const
904 {
905     ASSERT(isValueID());
906
907     switch (m_value.valueID) {
908     case CSSValueSlice:
909         return BoxDecorationBreak::Slice;
910     case CSSValueClone:
911         return BoxDecorationBreak::Clone;
912     default:
913         break;
914     }
915
916     ASSERT_NOT_REACHED();
917     return BoxDecorationBreak::Slice;
918 }
919 #endif
920
921 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Edge e)
922     : CSSValue(PrimitiveClass)
923 {
924     m_primitiveUnitType = CSS_VALUE_ID;
925     switch (e) {
926     case Edge::Top:
927         m_value.valueID = CSSValueTop;
928         break;
929     case Edge::Right:
930         m_value.valueID = CSSValueRight;
931         break;
932     case Edge::Bottom:
933         m_value.valueID = CSSValueBottom;
934         break;
935     case Edge::Left:
936         m_value.valueID = CSSValueLeft;
937         break;
938     }
939 }
940
941 template<> inline CSSPrimitiveValue::operator Edge() const
942 {
943     ASSERT(isValueID());
944
945     switch (m_value.valueID) {
946     case CSSValueTop:
947         return Edge::Top;
948     case CSSValueRight:
949         return Edge::Right;
950     case CSSValueBottom:
951         return Edge::Bottom;
952     case CSSValueLeft:
953         return Edge::Left;
954     default:
955         break;
956     }
957
958     ASSERT_NOT_REACHED();
959     return Edge::Top;
960 }
961
962 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxSizing e)
963     : CSSValue(PrimitiveClass)
964 {
965     m_primitiveUnitType = CSS_VALUE_ID;
966     switch (e) {
967     case BoxSizing::BorderBox:
968         m_value.valueID = CSSValueBorderBox;
969         break;
970     case BoxSizing::ContentBox:
971         m_value.valueID = CSSValueContentBox;
972         break;
973     }
974 }
975
976 template<> inline CSSPrimitiveValue::operator BoxSizing() const
977 {
978     ASSERT(isValueID());
979
980     switch (m_value.valueID) {
981     case CSSValueBorderBox:
982         return BoxSizing::BorderBox;
983     case CSSValueContentBox:
984         return BoxSizing::ContentBox;
985     default:
986         break;
987     }
988
989     ASSERT_NOT_REACHED();
990     return BoxSizing::BorderBox;
991 }
992
993 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxDirection e)
994     : CSSValue(PrimitiveClass)
995 {
996     m_primitiveUnitType = CSS_VALUE_ID;
997     switch (e) {
998     case BoxDirection::Normal:
999         m_value.valueID = CSSValueNormal;
1000         break;
1001     case BoxDirection::Reverse:
1002         m_value.valueID = CSSValueReverse;
1003         break;
1004     }
1005 }
1006
1007 template<> inline CSSPrimitiveValue::operator BoxDirection() const
1008 {
1009     ASSERT(isValueID());
1010
1011     switch (m_value.valueID) {
1012     case CSSValueNormal:
1013         return BoxDirection::Normal;
1014     case CSSValueReverse:
1015         return BoxDirection::Reverse;
1016     default:
1017         break;
1018     }
1019
1020     ASSERT_NOT_REACHED();
1021     return BoxDirection::Normal;
1022 }
1023
1024 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxLines e)
1025     : CSSValue(PrimitiveClass)
1026 {
1027     m_primitiveUnitType = CSS_VALUE_ID;
1028     switch (e) {
1029     case BoxLines::Single:
1030         m_value.valueID = CSSValueSingle;
1031         break;
1032     case BoxLines::Multiple:
1033         m_value.valueID = CSSValueMultiple;
1034         break;
1035     }
1036 }
1037
1038 template<> inline CSSPrimitiveValue::operator BoxLines() const
1039 {
1040     ASSERT(isValueID());
1041
1042     switch (m_value.valueID) {
1043     case CSSValueSingle:
1044         return BoxLines::Single;
1045     case CSSValueMultiple:
1046         return BoxLines::Multiple;
1047     default:
1048         break;
1049     }
1050
1051     ASSERT_NOT_REACHED();
1052     return BoxLines::Single;
1053 }
1054
1055 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BoxOrient e)
1056     : CSSValue(PrimitiveClass)
1057 {
1058     m_primitiveUnitType = CSS_VALUE_ID;
1059     switch (e) {
1060     case BoxOrient::Horizontal:
1061         m_value.valueID = CSSValueHorizontal;
1062         break;
1063     case BoxOrient::Vertical:
1064         m_value.valueID = CSSValueVertical;
1065         break;
1066     }
1067 }
1068
1069 template<> inline CSSPrimitiveValue::operator BoxOrient() const
1070 {
1071     ASSERT(isValueID());
1072
1073     switch (m_value.valueID) {
1074     case CSSValueHorizontal:
1075     case CSSValueInlineAxis:
1076         return BoxOrient::Horizontal;
1077     case CSSValueVertical:
1078     case CSSValueBlockAxis:
1079         return BoxOrient::Vertical;
1080     default:
1081         break;
1082     }
1083
1084     ASSERT_NOT_REACHED();
1085     return BoxOrient::Horizontal;
1086 }
1087
1088 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CaptionSide e)
1089     : CSSValue(PrimitiveClass)
1090 {
1091     m_primitiveUnitType = CSS_VALUE_ID;
1092     switch (e) {
1093     case CaptionSide::Left:
1094         m_value.valueID = CSSValueLeft;
1095         break;
1096     case CaptionSide::Right:
1097         m_value.valueID = CSSValueRight;
1098         break;
1099     case CaptionSide::Top:
1100         m_value.valueID = CSSValueTop;
1101         break;
1102     case CaptionSide::Bottom:
1103         m_value.valueID = CSSValueBottom;
1104         break;
1105     }
1106 }
1107
1108 template<> inline CSSPrimitiveValue::operator CaptionSide() const
1109 {
1110     ASSERT(isValueID());
1111
1112     switch (m_value.valueID) {
1113     case CSSValueLeft:
1114         return CaptionSide::Left;
1115     case CSSValueRight:
1116         return CaptionSide::Right;
1117     case CSSValueTop:
1118         return CaptionSide::Top;
1119     case CSSValueBottom:
1120         return CaptionSide::Bottom;
1121     default:
1122         break;
1123     }
1124
1125     ASSERT_NOT_REACHED();
1126     return CaptionSide::Top;
1127 }
1128
1129 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Clear e)
1130     : CSSValue(PrimitiveClass)
1131 {
1132     m_primitiveUnitType = CSS_VALUE_ID;
1133     switch (e) {
1134     case Clear::None:
1135         m_value.valueID = CSSValueNone;
1136         break;
1137     case Clear::Left:
1138         m_value.valueID = CSSValueLeft;
1139         break;
1140     case Clear::Right:
1141         m_value.valueID = CSSValueRight;
1142         break;
1143     case Clear::Both:
1144         m_value.valueID = CSSValueBoth;
1145         break;
1146     }
1147 }
1148
1149 template<> inline CSSPrimitiveValue::operator Clear() const
1150 {
1151     ASSERT(isValueID());
1152
1153     switch (m_value.valueID) {
1154     case CSSValueNone:
1155         return Clear::None;
1156     case CSSValueLeft:
1157         return Clear::Left;
1158     case CSSValueRight:
1159         return Clear::Right;
1160     case CSSValueBoth:
1161         return Clear::Both;
1162     default:
1163         break;
1164     }
1165
1166     ASSERT_NOT_REACHED();
1167     return Clear::None;
1168 }
1169
1170 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CursorType e)
1171     : CSSValue(PrimitiveClass)
1172 {
1173     m_primitiveUnitType = CSS_VALUE_ID;
1174     switch (e) {
1175     case CursorType::Auto:
1176         m_value.valueID = CSSValueAuto;
1177         break;
1178     case CursorType::Default:
1179         m_value.valueID = CSSValueDefault;
1180         break;
1181     case CursorType::None:
1182         m_value.valueID = CSSValueNone;
1183         break;
1184     case CursorType::ContextMenu:
1185         m_value.valueID = CSSValueContextMenu;
1186         break;
1187     case CursorType::Help:
1188         m_value.valueID = CSSValueHelp;
1189         break;
1190     case CursorType::Pointer:
1191         m_value.valueID = CSSValuePointer;
1192         break;
1193     case CursorType::Progress:
1194         m_value.valueID = CSSValueProgress;
1195         break;
1196     case CursorType::Wait:
1197         m_value.valueID = CSSValueWait;
1198         break;
1199     case CursorType::Cell:
1200         m_value.valueID = CSSValueCell;
1201         break;
1202     case CursorType::Crosshair:
1203         m_value.valueID = CSSValueCrosshair;
1204         break;
1205     case CursorType::Text:
1206         m_value.valueID = CSSValueText;
1207         break;
1208     case CursorType::VerticalText:
1209         m_value.valueID = CSSValueVerticalText;
1210         break;
1211     case CursorType::Alias:
1212         m_value.valueID = CSSValueAlias;
1213         break;
1214     case CursorType::Copy:
1215         m_value.valueID = CSSValueCopy;
1216         break;
1217     case CursorType::Move:
1218         m_value.valueID = CSSValueMove;
1219         break;
1220     case CursorType::NoDrop:
1221         m_value.valueID = CSSValueNoDrop;
1222         break;
1223     case CursorType::NotAllowed:
1224         m_value.valueID = CSSValueNotAllowed;
1225         break;
1226     case CursorType::Grab:
1227         m_value.valueID = CSSValueGrab;
1228         break;
1229     case CursorType::Grabbing:
1230         m_value.valueID = CSSValueGrabbing;
1231         break;
1232     case CursorType::EResize:
1233         m_value.valueID = CSSValueEResize;
1234         break;
1235     case CursorType::NResize:
1236         m_value.valueID = CSSValueNResize;
1237         break;
1238     case CursorType::NEResize:
1239         m_value.valueID = CSSValueNeResize;
1240         break;
1241     case CursorType::NWResize:
1242         m_value.valueID = CSSValueNwResize;
1243         break;
1244     case CursorType::SResize:
1245         m_value.valueID = CSSValueSResize;
1246         break;
1247     case CursorType::SEResize:
1248         m_value.valueID = CSSValueSeResize;
1249         break;
1250     case CursorType::SWResize:
1251         m_value.valueID = CSSValueSwResize;
1252         break;
1253     case CursorType::WResize:
1254         m_value.valueID = CSSValueWResize;
1255         break;
1256     case CursorType::EWResize:
1257         m_value.valueID = CSSValueEwResize;
1258         break;
1259     case CursorType::NSResize:
1260         m_value.valueID = CSSValueNsResize;
1261         break;
1262     case CursorType::NESWResize:
1263         m_value.valueID = CSSValueNeswResize;
1264         break;
1265     case CursorType::NWSEResize:
1266         m_value.valueID = CSSValueNwseResize;
1267         break;
1268     case CursorType::ColumnResize:
1269         m_value.valueID = CSSValueColResize;
1270         break;
1271     case CursorType::RowResize:
1272         m_value.valueID = CSSValueRowResize;
1273         break;
1274     case CursorType::AllScroll:
1275         m_value.valueID = CSSValueAllScroll;
1276         break;
1277     case CursorType::ZoomIn:
1278         m_value.valueID = CSSValueZoomIn;
1279         break;
1280     case CursorType::ZoomOut:
1281         m_value.valueID = CSSValueZoomOut;
1282         break;
1283     }
1284 }
1285
1286 template<> inline CSSPrimitiveValue::operator CursorType() const
1287 {
1288     ASSERT(isValueID());
1289     switch (m_value.valueID) {
1290     case CSSValueCopy:
1291         return CursorType::Copy;
1292     case CSSValueWebkitGrab:
1293         return CursorType::Grab;
1294     case CSSValueWebkitGrabbing:
1295         return CursorType::Grabbing;
1296     case CSSValueWebkitZoomIn:
1297         return CursorType::ZoomIn;
1298     case CSSValueWebkitZoomOut:
1299         return CursorType::ZoomOut;
1300     case CSSValueNone:
1301         return CursorType::None;
1302     default:
1303         return static_cast<CursorType>(m_value.valueID - CSSValueAuto);
1304     }
1305 }
1306
1307 #if ENABLE(CURSOR_VISIBILITY)
1308 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CursorVisibility e)
1309     : CSSValue(PrimitiveClass)
1310 {
1311     m_primitiveUnitType = CSS_VALUE_ID;
1312     switch (e) {
1313     case CursorVisibility::Auto:
1314         m_value.valueID = CSSValueAuto;
1315         break;
1316     case CursorVisibility::AutoHide:
1317         m_value.valueID = CSSValueAutoHide;
1318         break;
1319     }
1320 }
1321
1322 template<> inline CSSPrimitiveValue::operator CursorVisibility() const
1323 {
1324     ASSERT(isValueID());
1325
1326     if (m_value.valueID == CSSValueAuto)
1327         return CursorVisibility::Auto;
1328     if (m_value.valueID == CSSValueAutoHide)
1329         return CursorVisibility::AutoHide;
1330
1331     ASSERT_NOT_REACHED();
1332     return CursorVisibility::Auto;
1333 }
1334 #endif
1335
1336 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(DisplayType e)
1337     : CSSValue(PrimitiveClass)
1338 {
1339     m_primitiveUnitType = CSS_VALUE_ID;
1340     switch (e) {
1341     case DisplayType::Inline:
1342         m_value.valueID = CSSValueInline;
1343         break;
1344     case DisplayType::Block:
1345         m_value.valueID = CSSValueBlock;
1346         break;
1347     case DisplayType::ListItem:
1348         m_value.valueID = CSSValueListItem;
1349         break;
1350     case DisplayType::Compact:
1351         m_value.valueID = CSSValueCompact;
1352         break;
1353     case DisplayType::InlineBlock:
1354         m_value.valueID = CSSValueInlineBlock;
1355         break;
1356     case DisplayType::Table:
1357         m_value.valueID = CSSValueTable;
1358         break;
1359     case DisplayType::InlineTable:
1360         m_value.valueID = CSSValueInlineTable;
1361         break;
1362     case DisplayType::TableRowGroup:
1363         m_value.valueID = CSSValueTableRowGroup;
1364         break;
1365     case DisplayType::TableHeaderGroup:
1366         m_value.valueID = CSSValueTableHeaderGroup;
1367         break;
1368     case DisplayType::TableFooterGroup:
1369         m_value.valueID = CSSValueTableFooterGroup;
1370         break;
1371     case DisplayType::TableRow:
1372         m_value.valueID = CSSValueTableRow;
1373         break;
1374     case DisplayType::TableColumnGroup:
1375         m_value.valueID = CSSValueTableColumnGroup;
1376         break;
1377     case DisplayType::TableColumn:
1378         m_value.valueID = CSSValueTableColumn;
1379         break;
1380     case DisplayType::TableCell:
1381         m_value.valueID = CSSValueTableCell;
1382         break;
1383     case DisplayType::TableCaption:
1384         m_value.valueID = CSSValueTableCaption;
1385         break;
1386     case DisplayType::Box:
1387         m_value.valueID = CSSValueWebkitBox;
1388         break;
1389     case DisplayType::InlineBox:
1390         m_value.valueID = CSSValueWebkitInlineBox;
1391         break;
1392     case DisplayType::Flex:
1393     case DisplayType::WebKitFlex:
1394         m_value.valueID = CSSValueFlex;
1395         break;
1396     case DisplayType::InlineFlex:
1397     case DisplayType::WebKitInlineFlex:
1398         m_value.valueID = CSSValueInlineFlex;
1399         break;
1400     case DisplayType::Grid:
1401         m_value.valueID = CSSValueGrid;
1402         break;
1403     case DisplayType::InlineGrid:
1404         m_value.valueID = CSSValueInlineGrid;
1405         break;
1406     case DisplayType::None:
1407         m_value.valueID = CSSValueNone;
1408         break;
1409     case DisplayType::Contents:
1410         m_value.valueID = CSSValueContents;
1411         break;
1412     }
1413 }
1414
1415 template<> inline CSSPrimitiveValue::operator DisplayType() const
1416 {
1417     ASSERT(isValueID());
1418
1419     if (m_value.valueID == CSSValueNone)
1420         return DisplayType::None;
1421
1422     DisplayType display = static_cast<DisplayType>(m_value.valueID - CSSValueInline);
1423     ASSERT(display >= DisplayType::Inline && display <= DisplayType::None);
1424     if (display == DisplayType::WebKitFlex)
1425         return DisplayType::Flex;
1426     if (display == DisplayType::WebKitInlineFlex)
1427         return DisplayType::InlineFlex;
1428     return display;
1429 }
1430
1431 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EmptyCell e)
1432     : CSSValue(PrimitiveClass)
1433 {
1434     m_primitiveUnitType = CSS_VALUE_ID;
1435     switch (e) {
1436     case EmptyCell::Show:
1437         m_value.valueID = CSSValueShow;
1438         break;
1439     case EmptyCell::Hide:
1440         m_value.valueID = CSSValueHide;
1441         break;
1442     }
1443 }
1444
1445 template<> inline CSSPrimitiveValue::operator EmptyCell() const
1446 {
1447     ASSERT(isValueID());
1448
1449     switch (m_value.valueID) {
1450     case CSSValueShow:
1451         return EmptyCell::Show;
1452     case CSSValueHide:
1453         return EmptyCell::Hide;
1454     default:
1455         break;
1456     }
1457
1458     ASSERT_NOT_REACHED();
1459     return EmptyCell::Show;
1460 }
1461
1462 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FlexDirection e)
1463     : CSSValue(PrimitiveClass)
1464 {
1465     m_primitiveUnitType = CSS_VALUE_ID;
1466     switch (e) {
1467     case FlexDirection::Row:
1468         m_value.valueID = CSSValueRow;
1469         break;
1470     case FlexDirection::RowReverse:
1471         m_value.valueID = CSSValueRowReverse;
1472         break;
1473     case FlexDirection::Column:
1474         m_value.valueID = CSSValueColumn;
1475         break;
1476     case FlexDirection::ColumnReverse:
1477         m_value.valueID = CSSValueColumnReverse;
1478         break;
1479     }
1480 }
1481
1482 template<> inline CSSPrimitiveValue::operator FlexDirection() const
1483 {
1484     ASSERT(isValueID());
1485
1486     switch (m_value.valueID) {
1487     case CSSValueRow:
1488         return FlexDirection::Row;
1489     case CSSValueRowReverse:
1490         return FlexDirection::RowReverse;
1491     case CSSValueColumn:
1492         return FlexDirection::Column;
1493     case CSSValueColumnReverse:
1494         return FlexDirection::ColumnReverse;
1495     default:
1496         break;
1497     }
1498
1499     ASSERT_NOT_REACHED();
1500     return FlexDirection::Row;
1501 }
1502
1503 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(AlignContent e)
1504     : CSSValue(PrimitiveClass)
1505 {
1506     m_primitiveUnitType = CSS_VALUE_ID;
1507     switch (e) {
1508     case AlignContent::FlexStart:
1509         m_value.valueID = CSSValueFlexStart;
1510         break;
1511     case AlignContent::FlexEnd:
1512         m_value.valueID = CSSValueFlexEnd;
1513         break;
1514     case AlignContent::Center:
1515         m_value.valueID = CSSValueCenter;
1516         break;
1517     case AlignContent::SpaceBetween:
1518         m_value.valueID = CSSValueSpaceBetween;
1519         break;
1520     case AlignContent::SpaceAround:
1521         m_value.valueID = CSSValueSpaceAround;
1522         break;
1523     case AlignContent::Stretch:
1524         m_value.valueID = CSSValueStretch;
1525         break;
1526     }
1527 }
1528
1529 template<> inline CSSPrimitiveValue::operator AlignContent() const
1530 {
1531     ASSERT(isValueID());
1532
1533     switch (m_value.valueID) {
1534     case CSSValueFlexStart:
1535         return AlignContent::FlexStart;
1536     case CSSValueFlexEnd:
1537         return AlignContent::FlexEnd;
1538     case CSSValueCenter:
1539         return AlignContent::Center;
1540     case CSSValueSpaceBetween:
1541         return AlignContent::SpaceBetween;
1542     case CSSValueSpaceAround:
1543         return AlignContent::SpaceAround;
1544     case CSSValueStretch:
1545         return AlignContent::Stretch;
1546     default:
1547         break;
1548     }
1549
1550     ASSERT_NOT_REACHED();
1551     return AlignContent::Stretch;
1552 }
1553
1554 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FlexWrap e)
1555     : CSSValue(PrimitiveClass)
1556 {
1557     m_primitiveUnitType = CSS_VALUE_ID;
1558     switch (e) {
1559     case FlexWrap::NoWrap:
1560         m_value.valueID = CSSValueNowrap;
1561         break;
1562     case FlexWrap::Wrap:
1563         m_value.valueID = CSSValueWrap;
1564         break;
1565     case FlexWrap::Reverse:
1566         m_value.valueID = CSSValueWrapReverse;
1567         break;
1568     }
1569 }
1570
1571 template<> inline CSSPrimitiveValue::operator FlexWrap() const
1572 {
1573     ASSERT(isValueID());
1574
1575     switch (m_value.valueID) {
1576     case CSSValueNowrap:
1577         return FlexWrap::NoWrap;
1578     case CSSValueWrap:
1579         return FlexWrap::Wrap;
1580     case CSSValueWrapReverse:
1581         return FlexWrap::Reverse;
1582     default:
1583         break;
1584     }
1585
1586     ASSERT_NOT_REACHED();
1587     return FlexWrap::NoWrap;
1588 }
1589
1590 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Float e)
1591     : CSSValue(PrimitiveClass)
1592 {
1593     m_primitiveUnitType = CSS_VALUE_ID;
1594     switch (e) {
1595     case Float::No:
1596         m_value.valueID = CSSValueNone;
1597         break;
1598     case Float::Left:
1599         m_value.valueID = CSSValueLeft;
1600         break;
1601     case Float::Right:
1602         m_value.valueID = CSSValueRight;
1603         break;
1604     }
1605 }
1606
1607 template<> inline CSSPrimitiveValue::operator Float() const
1608 {
1609     ASSERT(isValueID());
1610
1611     switch (m_value.valueID) {
1612     case CSSValueLeft:
1613         return Float::Left;
1614     case CSSValueRight:
1615         return Float::Right;
1616     case CSSValueNone:
1617     case CSSValueCenter: // Non-standard CSS value.
1618         return Float::No;
1619     default:
1620         break;
1621     }
1622
1623     ASSERT_NOT_REACHED();
1624     return Float::No;
1625 }
1626
1627 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineBreak e)
1628     : CSSValue(PrimitiveClass)
1629 {
1630     m_primitiveUnitType = CSS_VALUE_ID;
1631     switch (e) {
1632     case LineBreak::Auto:
1633         m_value.valueID = CSSValueAuto;
1634         break;
1635     case LineBreak::Loose:
1636         m_value.valueID = CSSValueLoose;
1637         break;
1638     case LineBreak::Normal:
1639         m_value.valueID = CSSValueNormal;
1640         break;
1641     case LineBreak::Strict:
1642         m_value.valueID = CSSValueStrict;
1643         break;
1644     case LineBreak::AfterWhiteSpace:
1645         m_value.valueID = CSSValueAfterWhiteSpace;
1646         break;
1647     }
1648 }
1649
1650 template<> inline CSSPrimitiveValue::operator OptionSet<HangingPunctuation>() const
1651 {
1652     ASSERT(isValueID());
1653     
1654     switch (m_value.valueID) {
1655     case CSSValueNone:
1656         return OptionSet<HangingPunctuation> { };
1657     case CSSValueFirst:
1658         return HangingPunctuation::First;
1659     case CSSValueLast:
1660         return HangingPunctuation::Last;
1661     case CSSValueAllowEnd:
1662         return HangingPunctuation::AllowEnd;
1663     case CSSValueForceEnd:
1664         return HangingPunctuation::ForceEnd;
1665     default:
1666         break;
1667     }
1668     
1669     ASSERT_NOT_REACHED();
1670     return OptionSet<HangingPunctuation> { };
1671 }
1672
1673 template<> inline CSSPrimitiveValue::operator LineBreak() const
1674 {
1675     ASSERT(isValueID());
1676
1677     switch (m_value.valueID) {
1678     case CSSValueAuto:
1679         return LineBreak::Auto;
1680     case CSSValueLoose:
1681         return LineBreak::Loose;
1682     case CSSValueNormal:
1683         return LineBreak::Normal;
1684     case CSSValueStrict:
1685         return LineBreak::Strict;
1686     case CSSValueAfterWhiteSpace:
1687         return LineBreak::AfterWhiteSpace;
1688     default:
1689         break;
1690     }
1691
1692     ASSERT_NOT_REACHED();
1693     return LineBreak::Auto;
1694 }
1695
1696 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ListStylePosition e)
1697     : CSSValue(PrimitiveClass)
1698 {
1699     m_primitiveUnitType = CSS_VALUE_ID;
1700     switch (e) {
1701     case ListStylePosition::Outside:
1702         m_value.valueID = CSSValueOutside;
1703         break;
1704     case ListStylePosition::Inside:
1705         m_value.valueID = CSSValueInside;
1706         break;
1707     }
1708 }
1709
1710 template<> inline CSSPrimitiveValue::operator ListStylePosition() const
1711 {
1712     ASSERT(isValueID());
1713
1714     switch (m_value.valueID) {
1715     case CSSValueOutside:
1716         return ListStylePosition::Outside;
1717     case CSSValueInside:
1718         return ListStylePosition::Inside;
1719     default:
1720         break;
1721     }
1722
1723     ASSERT_NOT_REACHED();
1724     return ListStylePosition::Outside;
1725 }
1726
1727 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ListStyleType e)
1728     : CSSValue(PrimitiveClass)
1729 {
1730     m_primitiveUnitType = CSS_VALUE_ID;
1731     switch (e) {
1732     case ListStyleType::Afar:
1733         m_value.valueID = CSSValueAfar;
1734         break;
1735     case ListStyleType::Amharic:
1736         m_value.valueID = CSSValueAmharic;
1737         break;
1738     case ListStyleType::AmharicAbegede:
1739         m_value.valueID = CSSValueAmharicAbegede;
1740         break;
1741     case ListStyleType::ArabicIndic:
1742         m_value.valueID = CSSValueArabicIndic;
1743         break;
1744     case ListStyleType::Armenian:
1745         m_value.valueID = CSSValueArmenian;
1746         break;
1747     case ListStyleType::Asterisks:
1748         m_value.valueID = CSSValueAsterisks;
1749         break;
1750     case ListStyleType::Binary:
1751         m_value.valueID = CSSValueBinary;
1752         break;
1753     case ListStyleType::Bengali:
1754         m_value.valueID = CSSValueBengali;
1755         break;
1756     case ListStyleType::Cambodian:
1757         m_value.valueID = CSSValueCambodian;
1758         break;
1759     case ListStyleType::Circle:
1760         m_value.valueID = CSSValueCircle;
1761         break;
1762     case ListStyleType::CjkEarthlyBranch:
1763         m_value.valueID = CSSValueCjkEarthlyBranch;
1764         break;
1765     case ListStyleType::CjkHeavenlyStem:
1766         m_value.valueID = CSSValueCjkHeavenlyStem;
1767         break;
1768     case ListStyleType::CJKIdeographic:
1769         m_value.valueID = CSSValueCjkIdeographic;
1770         break;
1771     case ListStyleType::DecimalLeadingZero:
1772         m_value.valueID = CSSValueDecimalLeadingZero;
1773         break;
1774     case ListStyleType::Decimal:
1775         m_value.valueID = CSSValueDecimal;
1776         break;
1777     case ListStyleType::Devanagari:
1778         m_value.valueID = CSSValueDevanagari;
1779         break;
1780     case ListStyleType::Disc:
1781         m_value.valueID = CSSValueDisc;
1782         break;
1783     case ListStyleType::Ethiopic:
1784         m_value.valueID = CSSValueEthiopic;
1785         break;
1786     case ListStyleType::EthiopicAbegede:
1787         m_value.valueID = CSSValueEthiopicAbegede;
1788         break;
1789     case ListStyleType::EthiopicAbegedeAmEt:
1790         m_value.valueID = CSSValueEthiopicAbegedeAmEt;
1791         break;
1792     case ListStyleType::EthiopicAbegedeGez:
1793         m_value.valueID = CSSValueEthiopicAbegedeGez;
1794         break;
1795     case ListStyleType::EthiopicAbegedeTiEr:
1796         m_value.valueID = CSSValueEthiopicAbegedeTiEr;
1797         break;
1798     case ListStyleType::EthiopicAbegedeTiEt:
1799         m_value.valueID = CSSValueEthiopicAbegedeTiEt;
1800         break;
1801     case ListStyleType::EthiopicHalehameAaEr:
1802         m_value.valueID = CSSValueEthiopicHalehameAaEr;
1803         break;
1804     case ListStyleType::EthiopicHalehameAaEt:
1805         m_value.valueID = CSSValueEthiopicHalehameAaEt;
1806         break;
1807     case ListStyleType::EthiopicHalehameAmEt:
1808         m_value.valueID = CSSValueEthiopicHalehameAmEt;
1809         break;
1810     case ListStyleType::EthiopicHalehameGez:
1811         m_value.valueID = CSSValueEthiopicHalehameGez;
1812         break;
1813     case ListStyleType::EthiopicHalehameOmEt:
1814         m_value.valueID = CSSValueEthiopicHalehameOmEt;
1815         break;
1816     case ListStyleType::EthiopicHalehameSidEt:
1817         m_value.valueID = CSSValueEthiopicHalehameSidEt;
1818         break;
1819     case ListStyleType::EthiopicHalehameSoEt:
1820         m_value.valueID = CSSValueEthiopicHalehameSoEt;
1821         break;
1822     case ListStyleType::EthiopicHalehameTiEr:
1823         m_value.valueID = CSSValueEthiopicHalehameTiEr;
1824         break;
1825     case ListStyleType::EthiopicHalehameTiEt:
1826         m_value.valueID = CSSValueEthiopicHalehameTiEt;
1827         break;
1828     case ListStyleType::EthiopicHalehameTig:
1829         m_value.valueID = CSSValueEthiopicHalehameTig;
1830         break;
1831     case ListStyleType::Footnotes:
1832         m_value.valueID = CSSValueFootnotes;
1833         break;
1834     case ListStyleType::Georgian:
1835         m_value.valueID = CSSValueGeorgian;
1836         break;
1837     case ListStyleType::Gujarati:
1838         m_value.valueID = CSSValueGujarati;
1839         break;
1840     case ListStyleType::Gurmukhi:
1841         m_value.valueID = CSSValueGurmukhi;
1842         break;
1843     case ListStyleType::Hangul:
1844         m_value.valueID = CSSValueHangul;
1845         break;
1846     case ListStyleType::HangulConsonant:
1847         m_value.valueID = CSSValueHangulConsonant;
1848         break;
1849     case ListStyleType::Hebrew:
1850         m_value.valueID = CSSValueHebrew;
1851         break;
1852     case ListStyleType::Hiragana:
1853         m_value.valueID = CSSValueHiragana;
1854         break;
1855     case ListStyleType::HiraganaIroha:
1856         m_value.valueID = CSSValueHiraganaIroha;
1857         break;
1858     case ListStyleType::Kannada:
1859         m_value.valueID = CSSValueKannada;
1860         break;
1861     case ListStyleType::Katakana:
1862         m_value.valueID = CSSValueKatakana;
1863         break;
1864     case ListStyleType::KatakanaIroha:
1865         m_value.valueID = CSSValueKatakanaIroha;
1866         break;
1867     case ListStyleType::Khmer:
1868         m_value.valueID = CSSValueKhmer;
1869         break;
1870     case ListStyleType::Lao:
1871         m_value.valueID = CSSValueLao;
1872         break;
1873     case ListStyleType::LowerAlpha:
1874         m_value.valueID = CSSValueLowerAlpha;
1875         break;
1876     case ListStyleType::LowerArmenian:
1877         m_value.valueID = CSSValueLowerArmenian;
1878         break;
1879     case ListStyleType::LowerGreek:
1880         m_value.valueID = CSSValueLowerGreek;
1881         break;
1882     case ListStyleType::LowerHexadecimal:
1883         m_value.valueID = CSSValueLowerHexadecimal;
1884         break;
1885     case ListStyleType::LowerLatin:
1886         m_value.valueID = CSSValueLowerLatin;
1887         break;
1888     case ListStyleType::LowerNorwegian:
1889         m_value.valueID = CSSValueLowerNorwegian;
1890         break;
1891     case ListStyleType::LowerRoman:
1892         m_value.valueID = CSSValueLowerRoman;
1893         break;
1894     case ListStyleType::Malayalam:
1895         m_value.valueID = CSSValueMalayalam;
1896         break;
1897     case ListStyleType::Mongolian:
1898         m_value.valueID = CSSValueMongolian;
1899         break;
1900     case ListStyleType::Myanmar:
1901         m_value.valueID = CSSValueMyanmar;
1902         break;
1903     case ListStyleType::None:
1904         m_value.valueID = CSSValueNone;
1905         break;
1906     case ListStyleType::Octal:
1907         m_value.valueID = CSSValueOctal;
1908         break;
1909     case ListStyleType::Oriya:
1910         m_value.valueID = CSSValueOriya;
1911         break;
1912     case ListStyleType::Oromo:
1913         m_value.valueID = CSSValueOromo;
1914         break;
1915     case ListStyleType::Persian:
1916         m_value.valueID = CSSValuePersian;
1917         break;
1918     case ListStyleType::Sidama:
1919         m_value.valueID = CSSValueSidama;
1920         break;
1921     case ListStyleType::Somali:
1922         m_value.valueID = CSSValueSomali;
1923         break;
1924     case ListStyleType::Square:
1925         m_value.valueID = CSSValueSquare;
1926         break;
1927     case ListStyleType::Telugu:
1928         m_value.valueID = CSSValueTelugu;
1929         break;
1930     case ListStyleType::Thai:
1931         m_value.valueID = CSSValueThai;
1932         break;
1933     case ListStyleType::Tibetan:
1934         m_value.valueID = CSSValueTibetan;
1935         break;
1936     case ListStyleType::Tigre:
1937         m_value.valueID = CSSValueTigre;
1938         break;
1939     case ListStyleType::TigrinyaEr:
1940         m_value.valueID = CSSValueTigrinyaEr;
1941         break;
1942     case ListStyleType::TigrinyaErAbegede:
1943         m_value.valueID = CSSValueTigrinyaErAbegede;
1944         break;
1945     case ListStyleType::TigrinyaEt:
1946         m_value.valueID = CSSValueTigrinyaEt;
1947         break;
1948     case ListStyleType::TigrinyaEtAbegede:
1949         m_value.valueID = CSSValueTigrinyaEtAbegede;
1950         break;
1951     case ListStyleType::UpperAlpha:
1952         m_value.valueID = CSSValueUpperAlpha;
1953         break;
1954     case ListStyleType::UpperArmenian:
1955         m_value.valueID = CSSValueUpperArmenian;
1956         break;
1957     case ListStyleType::UpperGreek:
1958         m_value.valueID = CSSValueUpperGreek;
1959         break;
1960     case ListStyleType::UpperHexadecimal:
1961         m_value.valueID = CSSValueUpperHexadecimal;
1962         break;
1963     case ListStyleType::UpperLatin:
1964         m_value.valueID = CSSValueUpperLatin;
1965         break;
1966     case ListStyleType::UpperNorwegian:
1967         m_value.valueID = CSSValueUpperNorwegian;
1968         break;
1969     case ListStyleType::UpperRoman:
1970         m_value.valueID = CSSValueUpperRoman;
1971         break;
1972     case ListStyleType::Urdu:
1973         m_value.valueID = CSSValueUrdu;
1974         break;
1975     }
1976 }
1977
1978 template<> inline CSSPrimitiveValue::operator ListStyleType() const
1979 {
1980     ASSERT(isValueID());
1981
1982     switch (m_value.valueID) {
1983     case CSSValueNone:
1984         return ListStyleType::None;
1985     default:
1986         return static_cast<ListStyleType>(m_value.valueID - CSSValueDisc);
1987     }
1988 }
1989
1990 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(MarginCollapse e)
1991     : CSSValue(PrimitiveClass)
1992 {
1993     m_primitiveUnitType = CSS_VALUE_ID;
1994     switch (e) {
1995     case MarginCollapse::Collapse:
1996         m_value.valueID = CSSValueCollapse;
1997         break;
1998     case MarginCollapse::Separate:
1999         m_value.valueID = CSSValueSeparate;
2000         break;
2001     case MarginCollapse::Discard:
2002         m_value.valueID = CSSValueDiscard;
2003         break;
2004     }
2005 }
2006
2007 template<> inline CSSPrimitiveValue::operator MarginCollapse() const
2008 {
2009     ASSERT(isValueID());
2010
2011     switch (m_value.valueID) {
2012     case CSSValueCollapse:
2013         return MarginCollapse::Collapse;
2014     case CSSValueSeparate:
2015         return MarginCollapse::Separate;
2016     case CSSValueDiscard:
2017         return MarginCollapse::Discard;
2018     default:
2019         break;
2020     }
2021
2022     ASSERT_NOT_REACHED();
2023     return MarginCollapse::Collapse;
2024 }
2025
2026 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(MarqueeBehavior e)
2027     : CSSValue(PrimitiveClass)
2028 {
2029     m_primitiveUnitType = CSS_VALUE_ID;
2030     switch (e) {
2031     case MarqueeBehavior::None:
2032         m_value.valueID = CSSValueNone;
2033         break;
2034     case MarqueeBehavior::Scroll:
2035         m_value.valueID = CSSValueScroll;
2036         break;
2037     case MarqueeBehavior::Slide:
2038         m_value.valueID = CSSValueSlide;
2039         break;
2040     case MarqueeBehavior::Alternate:
2041         m_value.valueID = CSSValueAlternate;
2042         break;
2043     }
2044 }
2045
2046 template<> inline CSSPrimitiveValue::operator MarqueeBehavior() const
2047 {
2048     ASSERT(isValueID());
2049
2050     switch (m_value.valueID) {
2051     case CSSValueNone:
2052         return MarqueeBehavior::None;
2053     case CSSValueScroll:
2054         return MarqueeBehavior::Scroll;
2055     case CSSValueSlide:
2056         return MarqueeBehavior::Slide;
2057     case CSSValueAlternate:
2058         return MarqueeBehavior::Alternate;
2059     default:
2060         break;
2061     }
2062
2063     ASSERT_NOT_REACHED();
2064     return MarqueeBehavior::None;
2065 }
2066
2067 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(MarqueeDirection direction)
2068     : CSSValue(PrimitiveClass)
2069 {
2070     m_primitiveUnitType = CSS_VALUE_ID;
2071     switch (direction) {
2072     case MarqueeDirection::Forward:
2073         m_value.valueID = CSSValueForwards;
2074         break;
2075     case MarqueeDirection::Backward:
2076         m_value.valueID = CSSValueBackwards;
2077         break;
2078     case MarqueeDirection::Auto:
2079         m_value.valueID = CSSValueAuto;
2080         break;
2081     case MarqueeDirection::Up:
2082         m_value.valueID = CSSValueUp;
2083         break;
2084     case MarqueeDirection::Down:
2085         m_value.valueID = CSSValueDown;
2086         break;
2087     case MarqueeDirection::Left:
2088         m_value.valueID = CSSValueLeft;
2089         break;
2090     case MarqueeDirection::Right:
2091         m_value.valueID = CSSValueRight;
2092         break;
2093     }
2094 }
2095
2096 template<> inline CSSPrimitiveValue::operator MarqueeDirection() const
2097 {
2098     ASSERT(isValueID());
2099
2100     switch (m_value.valueID) {
2101     case CSSValueForwards:
2102         return MarqueeDirection::Forward;
2103     case CSSValueBackwards:
2104         return MarqueeDirection::Backward;
2105     case CSSValueAuto:
2106         return MarqueeDirection::Auto;
2107     case CSSValueAhead:
2108     case CSSValueUp: // We don't support vertical languages, so AHEAD just maps to UP.
2109         return MarqueeDirection::Up;
2110     case CSSValueReverse:
2111     case CSSValueDown: // REVERSE just maps to DOWN, since we don't do vertical text.
2112         return MarqueeDirection::Down;
2113     case CSSValueLeft:
2114         return MarqueeDirection::Left;
2115     case CSSValueRight:
2116         return MarqueeDirection::Right;
2117     default:
2118         break;
2119     }
2120
2121     ASSERT_NOT_REACHED();
2122     return MarqueeDirection::Auto;
2123 }
2124
2125 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(NBSPMode e)
2126     : CSSValue(PrimitiveClass)
2127 {
2128     m_primitiveUnitType = CSS_VALUE_ID;
2129     switch (e) {
2130     case NBSPMode::Normal:
2131         m_value.valueID = CSSValueNormal;
2132         break;
2133     case NBSPMode::Space:
2134         m_value.valueID = CSSValueSpace;
2135         break;
2136     }
2137 }
2138
2139 template<> inline CSSPrimitiveValue::operator NBSPMode() const
2140 {
2141     ASSERT(isValueID());
2142
2143     switch (m_value.valueID) {
2144     case CSSValueSpace:
2145         return NBSPMode::Space;
2146     case CSSValueNormal:
2147         return NBSPMode::Normal;
2148     default:
2149         break;
2150     }
2151
2152     ASSERT_NOT_REACHED();
2153     return NBSPMode::Normal;
2154 }
2155
2156 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Overflow e)
2157     : CSSValue(PrimitiveClass)
2158 {
2159     m_primitiveUnitType = CSS_VALUE_ID;
2160     switch (e) {
2161     case Overflow::Visible:
2162         m_value.valueID = CSSValueVisible;
2163         break;
2164     case Overflow::Hidden:
2165         m_value.valueID = CSSValueHidden;
2166         break;
2167     case Overflow::Scroll:
2168         m_value.valueID = CSSValueScroll;
2169         break;
2170     case Overflow::Auto:
2171         m_value.valueID = CSSValueAuto;
2172         break;
2173     case Overflow::PagedX:
2174         m_value.valueID = CSSValueWebkitPagedX;
2175         break;
2176     case Overflow::PagedY:
2177         m_value.valueID = CSSValueWebkitPagedY;
2178         break;
2179     }
2180 }
2181
2182 template<> inline CSSPrimitiveValue::operator Overflow() const
2183 {
2184     ASSERT(isValueID());
2185
2186     switch (m_value.valueID) {
2187     case CSSValueVisible:
2188         return Overflow::Visible;
2189     case CSSValueHidden:
2190         return Overflow::Hidden;
2191     case CSSValueScroll:
2192         return Overflow::Scroll;
2193     case CSSValueOverlay:
2194     case CSSValueAuto:
2195         return Overflow::Auto;
2196     case CSSValueWebkitPagedX:
2197         return Overflow::PagedX;
2198     case CSSValueWebkitPagedY:
2199         return Overflow::PagedY;
2200     default:
2201         break;
2202     }
2203
2204     ASSERT_NOT_REACHED();
2205     return Overflow::Visible;
2206 }
2207
2208 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BreakBetween e)
2209     : CSSValue(PrimitiveClass)
2210 {
2211     m_primitiveUnitType = CSS_VALUE_ID;
2212     switch (e) {
2213     case BreakBetween::Auto:
2214         m_value.valueID = CSSValueAuto;
2215         break;
2216     case BreakBetween::Avoid:
2217         m_value.valueID = CSSValueAvoid;
2218         break;
2219     case BreakBetween::AvoidColumn:
2220         m_value.valueID = CSSValueAvoidColumn;
2221         break;
2222     case BreakBetween::AvoidPage:
2223         m_value.valueID = CSSValueAvoidPage;
2224         break;
2225     case BreakBetween::Column:
2226         m_value.valueID = CSSValueColumn;
2227         break;
2228     case BreakBetween::Page:
2229         m_value.valueID = CSSValuePage;
2230         break;
2231     case BreakBetween::LeftPage:
2232         m_value.valueID = CSSValueLeft;
2233         break;
2234     case BreakBetween::RightPage:
2235         m_value.valueID = CSSValueRight;
2236         break;
2237     case BreakBetween::RectoPage:
2238         m_value.valueID = CSSValueRecto;
2239         break;
2240     case BreakBetween::VersoPage:
2241         m_value.valueID = CSSValueVerso;
2242         break;
2243     }
2244 }
2245
2246 template<> inline CSSPrimitiveValue::operator BreakBetween() const
2247 {
2248     ASSERT(isValueID());
2249
2250     switch (m_value.valueID) {
2251     case CSSValueAuto:
2252         return BreakBetween::Auto;
2253     case CSSValueAvoid:
2254         return BreakBetween::Avoid;
2255     case CSSValueAvoidColumn:
2256         return BreakBetween::AvoidColumn;
2257     case CSSValueAvoidPage:
2258         return BreakBetween::AvoidPage;
2259     case CSSValueColumn:
2260         return BreakBetween::Column;
2261     case CSSValuePage:
2262         return BreakBetween::Page;
2263     case CSSValueLeft:
2264         return BreakBetween::LeftPage;
2265     case CSSValueRight:
2266         return BreakBetween::RightPage;
2267     case CSSValueRecto:
2268         return BreakBetween::RectoPage;
2269     case CSSValueVerso:
2270         return BreakBetween::VersoPage;
2271     default:
2272         break;
2273     }
2274
2275     ASSERT_NOT_REACHED();
2276     return BreakBetween::Auto;
2277 }
2278
2279 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BreakInside e)
2280     : CSSValue(PrimitiveClass)
2281 {
2282     m_primitiveUnitType = CSS_VALUE_ID;
2283     switch (e) {
2284     case BreakInside::Auto:
2285         m_value.valueID = CSSValueAuto;
2286         break;
2287     case BreakInside::Avoid:
2288         m_value.valueID = CSSValueAvoid;
2289         break;
2290     case BreakInside::AvoidColumn:
2291         m_value.valueID = CSSValueAvoidColumn;
2292         break;
2293     case BreakInside::AvoidPage:
2294         m_value.valueID = CSSValueAvoidPage;
2295         break;
2296     }
2297 }
2298
2299 template<> inline CSSPrimitiveValue::operator BreakInside() const
2300 {
2301     ASSERT(isValueID());
2302     
2303     switch (m_value.valueID) {
2304     case CSSValueAuto:
2305         return BreakInside::Auto;
2306     case CSSValueAvoid:
2307         return BreakInside::Avoid;
2308     case CSSValueAvoidColumn:
2309         return BreakInside::AvoidColumn;
2310     case CSSValueAvoidPage:
2311         return BreakInside::AvoidPage;
2312     default:
2313         break;
2314     }
2315
2316     ASSERT_NOT_REACHED();
2317     return BreakInside::Auto;
2318 }
2319
2320 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(PositionType e)
2321     : CSSValue(PrimitiveClass)
2322 {
2323     m_primitiveUnitType = CSS_VALUE_ID;
2324     switch (e) {
2325     case PositionType::Static:
2326         m_value.valueID = CSSValueStatic;
2327         break;
2328     case PositionType::Relative:
2329         m_value.valueID = CSSValueRelative;
2330         break;
2331     case PositionType::Absolute:
2332         m_value.valueID = CSSValueAbsolute;
2333         break;
2334     case PositionType::Fixed:
2335         m_value.valueID = CSSValueFixed;
2336         break;
2337     case PositionType::Sticky:
2338         m_value.valueID = CSSValueSticky;
2339         break;
2340     }
2341 }
2342
2343 template<> inline CSSPrimitiveValue::operator PositionType() const
2344 {
2345     ASSERT(isValueID());
2346
2347     switch (m_value.valueID) {
2348     case CSSValueStatic:
2349         return PositionType::Static;
2350     case CSSValueRelative:
2351         return PositionType::Relative;
2352     case CSSValueAbsolute:
2353         return PositionType::Absolute;
2354     case CSSValueFixed:
2355         return PositionType::Fixed;
2356     case CSSValueSticky:
2357     case CSSValueWebkitSticky:
2358         return PositionType::Sticky;
2359     default:
2360         break;
2361     }
2362
2363     ASSERT_NOT_REACHED();
2364     return PositionType::Static;
2365 }
2366
2367 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Resize e)
2368     : CSSValue(PrimitiveClass)
2369 {
2370     m_primitiveUnitType = CSS_VALUE_ID;
2371     switch (e) {
2372     case Resize::Both:
2373         m_value.valueID = CSSValueBoth;
2374         break;
2375     case Resize::Horizontal:
2376         m_value.valueID = CSSValueHorizontal;
2377         break;
2378     case Resize::Vertical:
2379         m_value.valueID = CSSValueVertical;
2380         break;
2381     case Resize::None:
2382         m_value.valueID = CSSValueNone;
2383         break;
2384     }
2385 }
2386
2387 template<> inline CSSPrimitiveValue::operator Resize() const
2388 {
2389     ASSERT(isValueID());
2390
2391     switch (m_value.valueID) {
2392     case CSSValueBoth:
2393         return Resize::Both;
2394     case CSSValueHorizontal:
2395         return Resize::Horizontal;
2396     case CSSValueVertical:
2397         return Resize::Vertical;
2398     case CSSValueAuto:
2399         ASSERT_NOT_REACHED(); // Depends on settings, thus should be handled by the caller.
2400         return Resize::None;
2401     case CSSValueNone:
2402         return Resize::None;
2403     default:
2404         break;
2405     }
2406
2407     ASSERT_NOT_REACHED();
2408     return Resize::None;
2409 }
2410
2411 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TableLayoutType e)
2412     : CSSValue(PrimitiveClass)
2413 {
2414     m_primitiveUnitType = CSS_VALUE_ID;
2415     switch (e) {
2416     case TableLayoutType::Auto:
2417         m_value.valueID = CSSValueAuto;
2418         break;
2419     case TableLayoutType::Fixed:
2420         m_value.valueID = CSSValueFixed;
2421         break;
2422     }
2423 }
2424
2425 template<> inline CSSPrimitiveValue::operator TableLayoutType() const
2426 {
2427     ASSERT(isValueID());
2428
2429     switch (m_value.valueID) {
2430     case CSSValueFixed:
2431         return TableLayoutType::Fixed;
2432     case CSSValueAuto:
2433         return TableLayoutType::Auto;
2434     default:
2435         break;
2436     }
2437
2438     ASSERT_NOT_REACHED();
2439     return TableLayoutType::Auto;
2440 }
2441
2442 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextAlignMode e)
2443     : CSSValue(PrimitiveClass)
2444 {
2445     m_primitiveUnitType = CSS_VALUE_ID;
2446     switch (e) {
2447     case TextAlignMode::Start:
2448         m_value.valueID = CSSValueStart;
2449         break;
2450     case TextAlignMode::End:
2451         m_value.valueID = CSSValueEnd;
2452         break;
2453     case TextAlignMode::Left:
2454         m_value.valueID = CSSValueLeft;
2455         break;
2456     case TextAlignMode::Right:
2457         m_value.valueID = CSSValueRight;
2458         break;
2459     case TextAlignMode::Center:
2460         m_value.valueID = CSSValueCenter;
2461         break;
2462     case TextAlignMode::Justify:
2463         m_value.valueID = CSSValueJustify;
2464         break;
2465     case TextAlignMode::WebKitLeft:
2466         m_value.valueID = CSSValueWebkitLeft;
2467         break;
2468     case TextAlignMode::WebKitRight:
2469         m_value.valueID = CSSValueWebkitRight;
2470         break;
2471     case TextAlignMode::WebKitCenter:
2472         m_value.valueID = CSSValueWebkitCenter;
2473         break;
2474     }
2475 }
2476
2477 template<> inline CSSPrimitiveValue::operator TextAlignMode() const
2478 {
2479     ASSERT(isValueID());
2480
2481     switch (m_value.valueID) {
2482     case CSSValueWebkitAuto: // Legacy -webkit-auto. Eqiuvalent to start.
2483     case CSSValueStart:
2484         return TextAlignMode::Start;
2485     case CSSValueEnd:
2486         return TextAlignMode::End;
2487     default:
2488         return static_cast<TextAlignMode>(m_value.valueID - CSSValueLeft);
2489     }
2490 }
2491
2492 #if ENABLE(CSS3_TEXT)
2493 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextAlignLast e)
2494     : CSSValue(PrimitiveClass)
2495 {
2496     m_primitiveUnitType = CSS_VALUE_ID;
2497     switch (e) {
2498     case TextAlignLast::Start:
2499         m_value.valueID = CSSValueStart;
2500         break;
2501     case TextAlignLast::End:
2502         m_value.valueID = CSSValueEnd;
2503         break;
2504     case TextAlignLast::Left:
2505         m_value.valueID = CSSValueLeft;
2506         break;
2507     case TextAlignLast::Right:
2508         m_value.valueID = CSSValueRight;
2509         break;
2510     case TextAlignLast::Center:
2511         m_value.valueID = CSSValueCenter;
2512         break;
2513     case TextAlignLast::Justify:
2514         m_value.valueID = CSSValueJustify;
2515         break;
2516     case TextAlignLast::Auto:
2517         m_value.valueID = CSSValueAuto;
2518         break;
2519     }
2520 }
2521
2522 template<> inline CSSPrimitiveValue::operator TextAlignLast() const
2523 {
2524     ASSERT(isValueID());
2525
2526     switch (m_value.valueID) {
2527     case CSSValueAuto:
2528         return TextAlignLast::Auto;
2529     case CSSValueStart:
2530         return TextAlignLast::Start;
2531     case CSSValueEnd:
2532         return TextAlignLast::End;
2533     case CSSValueLeft:
2534         return TextAlignLast::Left;
2535     case CSSValueRight:
2536         return TextAlignLast::Right;
2537     case CSSValueCenter:
2538         return TextAlignLast::Center;
2539     case CSSValueJustify:
2540         return TextAlignLast::Justify;
2541     default:
2542         break;
2543     }
2544
2545     ASSERT_NOT_REACHED();
2546     return TextAlignLast::Auto;
2547 }
2548
2549 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextJustify e)
2550     : CSSValue(PrimitiveClass)
2551 {
2552     m_primitiveUnitType = CSS_VALUE_ID;
2553     switch (e) {
2554     case TextJustify::Auto:
2555         m_value.valueID = CSSValueAuto;
2556         break;
2557     case TextJustify::None:
2558         m_value.valueID = CSSValueNone;
2559         break;
2560     case TextJustify::InterWord:
2561         m_value.valueID = CSSValueInterWord;
2562         break;
2563     case TextJustify::Distribute:
2564         m_value.valueID = CSSValueDistribute;
2565         break;
2566     }
2567 }
2568
2569 template<> inline CSSPrimitiveValue::operator TextJustify() const
2570 {
2571     ASSERT(isValueID());
2572
2573     switch (m_value.valueID) {
2574     case CSSValueAuto:
2575         return TextJustify::Auto;
2576     case CSSValueNone:
2577         return TextJustify::None;
2578     case CSSValueInterWord:
2579         return TextJustify::InterWord;
2580     case CSSValueDistribute:
2581         return TextJustify::Distribute;
2582     default:
2583         break;
2584     }
2585
2586     ASSERT_NOT_REACHED();
2587     return TextJustify::Auto;
2588 }
2589 #endif // CSS3_TEXT
2590
2591 template<> inline CSSPrimitiveValue::operator OptionSet<TextDecoration>() const
2592 {
2593     ASSERT(isValueID());
2594
2595     switch (m_value.valueID) {
2596     case CSSValueNone:
2597         return OptionSet<TextDecoration> { };
2598     case CSSValueUnderline:
2599         return TextDecoration::Underline;
2600     case CSSValueOverline:
2601         return TextDecoration::Overline;
2602     case CSSValueLineThrough:
2603         return TextDecoration::LineThrough;
2604     case CSSValueBlink:
2605         return TextDecoration::Blink;
2606 #if ENABLE(LETTERPRESS)
2607     case CSSValueWebkitLetterpress:
2608         return TextDecoration::Letterpress;
2609 #endif
2610     default:
2611         break;
2612     }
2613
2614     ASSERT_NOT_REACHED();
2615     return OptionSet<TextDecoration> { };
2616 }
2617
2618 template<> inline CSSPrimitiveValue::operator TextDecorationStyle() const
2619 {
2620     ASSERT(isValueID());
2621
2622     switch (m_value.valueID) {
2623     case CSSValueSolid:
2624         return TextDecorationStyle::Solid;
2625     case CSSValueDouble:
2626         return TextDecorationStyle::Double;
2627     case CSSValueDotted:
2628         return TextDecorationStyle::Dotted;
2629     case CSSValueDashed:
2630         return TextDecorationStyle::Dashed;
2631     case CSSValueWavy:
2632         return TextDecorationStyle::Wavy;
2633     default:
2634         break;
2635     }
2636
2637     ASSERT_NOT_REACHED();
2638     return TextDecorationStyle::Solid;
2639 }
2640
2641 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextUnderlinePosition position)
2642     : CSSValue(PrimitiveClass)
2643 {
2644     m_primitiveUnitType = CSS_VALUE_ID;
2645     switch (position) {
2646     case TextUnderlinePosition::Auto:
2647         m_value.valueID = CSSValueAuto;
2648         break;
2649     case TextUnderlinePosition::Under:
2650         m_value.valueID = CSSValueUnder;
2651         break;
2652     case TextUnderlinePosition::FromFont:
2653         m_value.valueID = CSSValueFromFont;
2654         break;
2655     }
2656
2657     // FIXME: Implement support for 'under left' and 'under right' values.
2658 }
2659
2660 template<> inline CSSPrimitiveValue::operator TextUnderlinePosition() const
2661 {
2662     ASSERT(isValueID());
2663
2664     switch (m_value.valueID) {
2665     case CSSValueAuto:
2666         return TextUnderlinePosition::Auto;
2667     case CSSValueUnder:
2668         return TextUnderlinePosition::Under;
2669     case CSSValueFromFont:
2670         return TextUnderlinePosition::FromFont;
2671     default:
2672         break;
2673     }
2674
2675     // FIXME: Implement support for 'under left' and 'under right' values.
2676     ASSERT_NOT_REACHED();
2677     return TextUnderlinePosition::Auto;
2678 }
2679
2680 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextSecurity e)
2681     : CSSValue(PrimitiveClass)
2682 {
2683     m_primitiveUnitType = CSS_VALUE_ID;
2684     switch (e) {
2685     case TextSecurity::None:
2686         m_value.valueID = CSSValueNone;
2687         break;
2688     case TextSecurity::Disc:
2689         m_value.valueID = CSSValueDisc;
2690         break;
2691     case TextSecurity::Circle:
2692         m_value.valueID = CSSValueCircle;
2693         break;
2694     case TextSecurity::Square:
2695         m_value.valueID = CSSValueSquare;
2696         break;
2697     }
2698 }
2699
2700 template<> inline CSSPrimitiveValue::operator TextSecurity() const
2701 {
2702     ASSERT(isValueID());
2703
2704     switch (m_value.valueID) {
2705     case CSSValueNone:
2706         return TextSecurity::None;
2707     case CSSValueDisc:
2708         return TextSecurity::Disc;
2709     case CSSValueCircle:
2710         return TextSecurity::Circle;
2711     case CSSValueSquare:
2712         return TextSecurity::Square;
2713     default:
2714         break;
2715     }
2716
2717     ASSERT_NOT_REACHED();
2718     return TextSecurity::None;
2719 }
2720
2721 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextTransform e)
2722     : CSSValue(PrimitiveClass)
2723 {
2724     m_primitiveUnitType = CSS_VALUE_ID;
2725     switch (e) {
2726     case TextTransform::Capitalize:
2727         m_value.valueID = CSSValueCapitalize;
2728         break;
2729     case TextTransform::Uppercase:
2730         m_value.valueID = CSSValueUppercase;
2731         break;
2732     case TextTransform::Lowercase:
2733         m_value.valueID = CSSValueLowercase;
2734         break;
2735     case TextTransform::None:
2736         m_value.valueID = CSSValueNone;
2737         break;
2738     }
2739 }
2740
2741 template<> inline CSSPrimitiveValue::operator TextTransform() const
2742 {
2743     ASSERT(isValueID());
2744
2745     switch (m_value.valueID) {
2746     case CSSValueCapitalize:
2747         return TextTransform::Capitalize;
2748     case CSSValueUppercase:
2749         return TextTransform::Uppercase;
2750     case CSSValueLowercase:
2751         return TextTransform::Lowercase;
2752     case CSSValueNone:
2753         return TextTransform::None;
2754     default:
2755         break;
2756     }
2757
2758     ASSERT_NOT_REACHED();
2759     return TextTransform::None;
2760 }
2761
2762 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUnicodeBidi e)
2763     : CSSValue(PrimitiveClass)
2764 {
2765     m_primitiveUnitType = CSS_VALUE_ID;
2766     switch (e) {
2767     case UBNormal:
2768         m_value.valueID = CSSValueNormal;
2769         break;
2770     case Embed:
2771         m_value.valueID = CSSValueEmbed;
2772         break;
2773     case Override:
2774         m_value.valueID = CSSValueBidiOverride;
2775         break;
2776     case Isolate:
2777         m_value.valueID = CSSValueIsolate;
2778         break;
2779     case IsolateOverride:
2780         m_value.valueID = CSSValueIsolateOverride;
2781         break;
2782     case Plaintext:
2783         m_value.valueID = CSSValuePlaintext;
2784         break;
2785     }
2786 }
2787
2788 template<> inline CSSPrimitiveValue::operator EUnicodeBidi() const
2789 {
2790     ASSERT(isValueID());
2791
2792     switch (m_value.valueID) {
2793     case CSSValueNormal:
2794         return UBNormal;
2795     case CSSValueEmbed:
2796         return Embed;
2797     case CSSValueBidiOverride:
2798         return Override;
2799     case CSSValueIsolate:
2800     case CSSValueWebkitIsolate:
2801         return Isolate;
2802     case CSSValueIsolateOverride:
2803     case CSSValueWebkitIsolateOverride:
2804         return IsolateOverride;
2805     case CSSValuePlaintext:
2806     case CSSValueWebkitPlaintext:
2807         return Plaintext;
2808     default:
2809         break;
2810     }
2811
2812     ASSERT_NOT_REACHED();
2813     return UBNormal;
2814 }
2815
2816 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserDrag e)
2817     : CSSValue(PrimitiveClass)
2818 {
2819     m_primitiveUnitType = CSS_VALUE_ID;
2820     switch (e) {
2821     case UserDrag::Auto:
2822         m_value.valueID = CSSValueAuto;
2823         break;
2824     case UserDrag::None:
2825         m_value.valueID = CSSValueNone;
2826         break;
2827     case UserDrag::Element:
2828         m_value.valueID = CSSValueElement;
2829         break;
2830     default:
2831         break;
2832     }
2833 }
2834
2835 template<> inline CSSPrimitiveValue::operator UserDrag() const
2836 {
2837     ASSERT(isValueID());
2838
2839     switch (m_value.valueID) {
2840     case CSSValueAuto:
2841         return UserDrag::Auto;
2842     case CSSValueNone:
2843         return UserDrag::None;
2844     case CSSValueElement:
2845         return UserDrag::Element;
2846     default:
2847         break;
2848     }
2849
2850     ASSERT_NOT_REACHED();
2851     return UserDrag::Auto;
2852 }
2853
2854 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserModify e)
2855     : CSSValue(PrimitiveClass)
2856 {
2857     m_primitiveUnitType = CSS_VALUE_ID;
2858     switch (e) {
2859     case UserModify::ReadOnly:
2860         m_value.valueID = CSSValueReadOnly;
2861         break;
2862     case UserModify::ReadWrite:
2863         m_value.valueID = CSSValueReadWrite;
2864         break;
2865     case UserModify::ReadWritePlaintextOnly:
2866         m_value.valueID = CSSValueReadWritePlaintextOnly;
2867         break;
2868     }
2869 }
2870
2871 template<> inline CSSPrimitiveValue::operator UserModify() const
2872 {
2873     ASSERT(isValueID());
2874
2875     switch (m_value.valueID) {
2876     case CSSValueReadOnly:
2877         return UserModify::ReadOnly;
2878     case CSSValueReadWrite:
2879         return UserModify::ReadWrite;
2880     case CSSValueReadWritePlaintextOnly:
2881         return UserModify::ReadWritePlaintextOnly;
2882     default:
2883         break;
2884     }
2885
2886     ASSERT_NOT_REACHED();
2887     return UserModify::ReadOnly;
2888 }
2889
2890 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserSelect e)
2891     : CSSValue(PrimitiveClass)
2892 {
2893     m_primitiveUnitType = CSS_VALUE_ID;
2894     switch (e) {
2895     case UserSelect::None:
2896         m_value.valueID = CSSValueNone;
2897         break;
2898     case UserSelect::Text:
2899         m_value.valueID = CSSValueText;
2900         break;
2901     case UserSelect::All:
2902         m_value.valueID = CSSValueAll;
2903         break;
2904     }
2905 }
2906
2907 template<> inline CSSPrimitiveValue::operator UserSelect() const
2908 {
2909     ASSERT(isValueID());
2910
2911     switch (m_value.valueID) {
2912     case CSSValueAuto:
2913         return UserSelect::Text;
2914     case CSSValueNone:
2915         return UserSelect::None;
2916     case CSSValueText:
2917         return UserSelect::Text;
2918     case CSSValueAll:
2919         return UserSelect::All;
2920     default:
2921         break;
2922     }
2923
2924     ASSERT_NOT_REACHED();
2925     return UserSelect::Text;
2926 }
2927
2928 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(VerticalAlign a)
2929     : CSSValue(PrimitiveClass)
2930 {
2931     m_primitiveUnitType = CSS_VALUE_ID;
2932     switch (a) {
2933     case VerticalAlign::Top:
2934         m_value.valueID = CSSValueTop;
2935         break;
2936     case VerticalAlign::Bottom:
2937         m_value.valueID = CSSValueBottom;
2938         break;
2939     case VerticalAlign::Middle:
2940         m_value.valueID = CSSValueMiddle;
2941         break;
2942     case VerticalAlign::Baseline:
2943         m_value.valueID = CSSValueBaseline;
2944         break;
2945     case VerticalAlign::TextBottom:
2946         m_value.valueID = CSSValueTextBottom;
2947         break;
2948     case VerticalAlign::TextTop:
2949         m_value.valueID = CSSValueTextTop;
2950         break;
2951     case VerticalAlign::Sub:
2952         m_value.valueID = CSSValueSub;
2953         break;
2954     case VerticalAlign::Super:
2955         m_value.valueID = CSSValueSuper;
2956         break;
2957     case VerticalAlign::BaselineMiddle:
2958         m_value.valueID = CSSValueWebkitBaselineMiddle;
2959         break;
2960     case VerticalAlign::Length:
2961         m_value.valueID = CSSValueInvalid;
2962     }
2963 }
2964
2965 template<> inline CSSPrimitiveValue::operator VerticalAlign() const
2966 {
2967     ASSERT(isValueID());
2968
2969     switch (m_value.valueID) {
2970     case CSSValueTop:
2971         return VerticalAlign::Top;
2972     case CSSValueBottom:
2973         return VerticalAlign::Bottom;
2974     case CSSValueMiddle:
2975         return VerticalAlign::Middle;
2976     case CSSValueBaseline:
2977         return VerticalAlign::Baseline;
2978     case CSSValueTextBottom:
2979         return VerticalAlign::TextBottom;
2980     case CSSValueTextTop:
2981         return VerticalAlign::TextTop;
2982     case CSSValueSub:
2983         return VerticalAlign::Sub;
2984     case CSSValueSuper:
2985         return VerticalAlign::Super;
2986     case CSSValueWebkitBaselineMiddle:
2987         return VerticalAlign::BaselineMiddle;
2988     default:
2989         break;
2990     }
2991
2992     ASSERT_NOT_REACHED();
2993     return VerticalAlign::Top;
2994 }
2995
2996 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Visibility e)
2997     : CSSValue(PrimitiveClass)
2998 {
2999     m_primitiveUnitType = CSS_VALUE_ID;
3000     switch (e) {
3001     case Visibility::Visible:
3002         m_value.valueID = CSSValueVisible;
3003         break;
3004     case Visibility::Hidden:
3005         m_value.valueID = CSSValueHidden;
3006         break;
3007     case Visibility::Collapse:
3008         m_value.valueID = CSSValueCollapse;
3009         break;
3010     }
3011 }
3012
3013 template<> inline CSSPrimitiveValue::operator Visibility() const
3014 {
3015     ASSERT(isValueID());
3016
3017     switch (m_value.valueID) {
3018     case CSSValueHidden:
3019         return Visibility::Hidden;
3020     case CSSValueVisible:
3021         return Visibility::Visible;
3022     case CSSValueCollapse:
3023         return Visibility::Collapse;
3024     default:
3025         break;
3026     }
3027
3028     ASSERT_NOT_REACHED();
3029     return Visibility::Visible;
3030 }
3031
3032 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WhiteSpace e)
3033     : CSSValue(PrimitiveClass)
3034 {
3035     m_primitiveUnitType = CSS_VALUE_ID;
3036     switch (e) {
3037     case WhiteSpace::Normal:
3038         m_value.valueID = CSSValueNormal;
3039         break;
3040     case WhiteSpace::Pre:
3041         m_value.valueID = CSSValuePre;
3042         break;
3043     case WhiteSpace::PreWrap:
3044         m_value.valueID = CSSValuePreWrap;
3045         break;
3046     case WhiteSpace::PreLine:
3047         m_value.valueID = CSSValuePreLine;
3048         break;
3049     case WhiteSpace::NoWrap:
3050         m_value.valueID = CSSValueNowrap;
3051         break;
3052     case WhiteSpace::KHTMLNoWrap:
3053         m_value.valueID = CSSValueWebkitNowrap;
3054         break;
3055     case WhiteSpace::BreakSpaces:
3056         m_value.valueID = CSSValueBreakSpaces;
3057         break;
3058     }
3059 }
3060
3061 template<> inline CSSPrimitiveValue::operator WhiteSpace() const
3062 {
3063     ASSERT(isValueID());
3064
3065     switch (m_value.valueID) {
3066     case CSSValueWebkitNowrap:
3067         return WhiteSpace::KHTMLNoWrap;
3068     case CSSValueNowrap:
3069         return WhiteSpace::NoWrap;
3070     case CSSValuePre:
3071         return WhiteSpace::Pre;
3072     case CSSValuePreWrap:
3073         return WhiteSpace::PreWrap;
3074     case CSSValuePreLine:
3075         return WhiteSpace::PreLine;
3076     case CSSValueNormal:
3077         return WhiteSpace::Normal;
3078     case CSSValueBreakSpaces:
3079         return WhiteSpace::BreakSpaces;
3080     default:
3081         break;
3082     }
3083
3084     ASSERT_NOT_REACHED();
3085     return WhiteSpace::Normal;
3086 }
3087
3088 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WordBreak e)
3089     : CSSValue(PrimitiveClass)
3090 {
3091     m_primitiveUnitType = CSS_VALUE_ID;
3092     switch (e) {
3093     case WordBreak::Normal:
3094         m_value.valueID = CSSValueNormal;
3095         break;
3096     case WordBreak::BreakAll:
3097         m_value.valueID = CSSValueBreakAll;
3098         break;
3099     case WordBreak::KeepAll:
3100         m_value.valueID = CSSValueKeepAll;
3101         break;
3102     case WordBreak::BreakWord:
3103         m_value.valueID = CSSValueBreakWord;
3104         break;
3105     }
3106 }
3107
3108 template<> inline CSSPrimitiveValue::operator WordBreak() const
3109 {
3110     ASSERT(isValueID());
3111
3112     switch (m_value.valueID) {
3113     case CSSValueBreakAll:
3114         return WordBreak::BreakAll;
3115     case CSSValueKeepAll:
3116         return WordBreak::KeepAll;
3117     case CSSValueBreakWord:
3118         return WordBreak::BreakWord;
3119     case CSSValueNormal:
3120         return WordBreak::Normal;
3121     default:
3122         break;
3123     }
3124
3125     ASSERT_NOT_REACHED();
3126     return WordBreak::Normal;
3127 }
3128
3129 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(OverflowWrap e)
3130     : CSSValue(PrimitiveClass)
3131 {
3132     m_primitiveUnitType = CSS_VALUE_ID;
3133     switch (e) {
3134     case OverflowWrap::Normal:
3135         m_value.valueID = CSSValueNormal;
3136         break;
3137     case OverflowWrap::Break:
3138         m_value.valueID = CSSValueBreakWord;
3139         break;
3140     }
3141 }
3142
3143 template<> inline CSSPrimitiveValue::operator OverflowWrap() const
3144 {
3145     ASSERT(isValueID());
3146
3147     switch (m_value.valueID) {
3148     case CSSValueBreakWord:
3149         return OverflowWrap::Break;
3150     case CSSValueNormal:
3151         return OverflowWrap::Normal;
3152     default:
3153         break;
3154     }
3155
3156     ASSERT_NOT_REACHED();
3157     return OverflowWrap::Normal;
3158 }
3159
3160 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextDirection e)
3161     : CSSValue(PrimitiveClass)
3162 {
3163     m_primitiveUnitType = CSS_VALUE_ID;
3164     switch (e) {
3165     case TextDirection::LTR:
3166         m_value.valueID = CSSValueLtr;
3167         break;
3168     case TextDirection::RTL:
3169         m_value.valueID = CSSValueRtl;
3170         break;
3171     }
3172 }
3173
3174 template<> inline CSSPrimitiveValue::operator TextDirection() const
3175 {
3176     ASSERT(isValueID());
3177
3178     switch (m_value.valueID) {
3179     case CSSValueLtr:
3180         return TextDirection::LTR;
3181     case CSSValueRtl:
3182         return TextDirection::RTL;
3183     default:
3184         break;
3185     }
3186
3187     ASSERT_NOT_REACHED();
3188     return TextDirection::LTR;
3189 }
3190
3191 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WritingMode e)
3192     : CSSValue(PrimitiveClass)
3193 {
3194     m_primitiveUnitType = CSS_VALUE_ID;
3195     switch (e) {
3196     case TopToBottomWritingMode:
3197         m_value.valueID = CSSValueHorizontalTb;
3198         break;
3199     case RightToLeftWritingMode:
3200         m_value.valueID = CSSValueVerticalRl;
3201         break;
3202     case LeftToRightWritingMode:
3203         m_value.valueID = CSSValueVerticalLr;
3204         break;
3205     case BottomToTopWritingMode:
3206         m_value.valueID = CSSValueHorizontalBt;
3207         break;
3208     }
3209 }
3210
3211 template<> inline CSSPrimitiveValue::operator WritingMode() const
3212 {
3213     ASSERT(isValueID());
3214
3215     switch (m_value.valueID) {
3216     case CSSValueHorizontalTb:
3217     case CSSValueLr:
3218     case CSSValueLrTb:
3219     case CSSValueRl:
3220     case CSSValueRlTb:
3221         return TopToBottomWritingMode;
3222     case CSSValueVerticalRl:
3223     case CSSValueTb:
3224     case CSSValueTbRl:
3225         return RightToLeftWritingMode;
3226     case CSSValueVerticalLr:
3227         return LeftToRightWritingMode;
3228     case CSSValueHorizontalBt:
3229         return BottomToTopWritingMode;
3230     default:
3231         break;
3232     }
3233
3234     ASSERT_NOT_REACHED();
3235     return TopToBottomWritingMode;
3236 }
3237
3238 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextCombine e)
3239     : CSSValue(PrimitiveClass)
3240 {
3241     m_primitiveUnitType = CSS_VALUE_ID;
3242     switch (e) {
3243     case TextCombine::None:
3244         m_value.valueID = CSSValueNone;
3245         break;
3246     case TextCombine::Horizontal:
3247         m_value.valueID = CSSValueHorizontal;
3248         break;
3249     }
3250 }
3251
3252 template<> inline CSSPrimitiveValue::operator TextCombine() const
3253 {
3254     ASSERT(isValueID());
3255
3256     switch (m_value.valueID) {
3257     case CSSValueNone:
3258         return TextCombine::None;
3259     case CSSValueHorizontal:
3260         return TextCombine::Horizontal;
3261     default:
3262         break;
3263     }
3264
3265     ASSERT_NOT_REACHED();
3266     return TextCombine::None;
3267 }
3268
3269 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(RubyPosition position)
3270     : CSSValue(PrimitiveClass)
3271 {
3272     m_primitiveUnitType = CSS_VALUE_ID;
3273     switch (position) {
3274     case RubyPosition::Before:
3275         m_value.valueID = CSSValueBefore;
3276         break;
3277     case RubyPosition::After:
3278         m_value.valueID = CSSValueAfter;
3279         break;
3280     case RubyPosition::InterCharacter:
3281         m_value.valueID = CSSValueInterCharacter;
3282         break;
3283     }
3284 }
3285
3286 template<> inline CSSPrimitiveValue::operator RubyPosition() const
3287 {
3288     ASSERT(isValueID());
3289
3290     switch (m_value.valueID) {
3291     case CSSValueBefore:
3292         return RubyPosition::Before;
3293     case CSSValueAfter:
3294         return RubyPosition::After;
3295     case CSSValueInterCharacter:
3296         return RubyPosition::InterCharacter;
3297     default:
3298         break;
3299     }
3300
3301     ASSERT_NOT_REACHED();
3302     return RubyPosition::Before;
3303 }
3304
3305 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextOverflow overflow)
3306     : CSSValue(PrimitiveClass)
3307 {
3308     m_primitiveUnitType = CSS_VALUE_ID;
3309     switch (overflow) {
3310     case TextOverflow::Clip:
3311         m_value.valueID = CSSValueClip;
3312         break;
3313     case TextOverflow::Ellipsis:
3314         m_value.valueID = CSSValueEllipsis;
3315         break;
3316     }
3317 }
3318
3319 template<> inline CSSPrimitiveValue::operator TextOverflow() const
3320 {
3321     ASSERT(isValueID());
3322
3323     switch (m_value.valueID) {
3324     case CSSValueClip:
3325         return TextOverflow::Clip;
3326     case CSSValueEllipsis:
3327         return TextOverflow::Ellipsis;
3328     default:
3329         break;
3330     }
3331
3332     ASSERT_NOT_REACHED();
3333     return TextOverflow::Clip;
3334 }
3335
3336 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisFill fill)
3337     : CSSValue(PrimitiveClass)
3338 {
3339     m_primitiveUnitType = CSS_VALUE_ID;
3340     switch (fill) {
3341     case TextEmphasisFill::Filled:
3342         m_value.valueID = CSSValueFilled;
3343         break;
3344     case TextEmphasisFill::Open:
3345         m_value.valueID = CSSValueOpen;
3346         break;
3347     }
3348 }
3349
3350 template<> inline CSSPrimitiveValue::operator TextEmphasisFill() const
3351 {
3352     ASSERT(isValueID());
3353
3354     switch (m_value.valueID) {
3355     case CSSValueFilled:
3356         return TextEmphasisFill::Filled;
3357     case CSSValueOpen:
3358         return TextEmphasisFill::Open;
3359     default:
3360         break;
3361     }
3362
3363     ASSERT_NOT_REACHED();
3364     return TextEmphasisFill::Filled;
3365 }
3366
3367 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisMark mark)
3368     : CSSValue(PrimitiveClass)
3369 {
3370     m_primitiveUnitType = CSS_VALUE_ID;
3371     switch (mark) {
3372     case TextEmphasisMark::Dot:
3373         m_value.valueID = CSSValueDot;
3374         break;
3375     case TextEmphasisMark::Circle:
3376         m_value.valueID = CSSValueCircle;
3377         break;
3378     case TextEmphasisMark::DoubleCircle:
3379         m_value.valueID = CSSValueDoubleCircle;
3380         break;
3381     case TextEmphasisMark::Triangle:
3382         m_value.valueID = CSSValueTriangle;
3383         break;
3384     case TextEmphasisMark::Sesame:
3385         m_value.valueID = CSSValueSesame;
3386         break;
3387     case TextEmphasisMark::None:
3388     case TextEmphasisMark::Auto:
3389     case TextEmphasisMark::Custom:
3390         ASSERT_NOT_REACHED();
3391         m_value.valueID = CSSValueNone;
3392         break;
3393     }
3394 }
3395
3396 template<> inline CSSPrimitiveValue::operator TextEmphasisMark() const
3397 {
3398     ASSERT(isValueID());
3399
3400     switch (m_value.valueID) {
3401     case CSSValueNone:
3402         return TextEmphasisMark::None;
3403     case CSSValueDot:
3404         return TextEmphasisMark::Dot;
3405     case CSSValueCircle:
3406         return TextEmphasisMark::Circle;
3407     case CSSValueDoubleCircle:
3408         return TextEmphasisMark::DoubleCircle;
3409     case CSSValueTriangle:
3410         return TextEmphasisMark::Triangle;
3411     case CSSValueSesame:
3412         return TextEmphasisMark::Sesame;
3413     default:
3414         break;
3415     }
3416
3417     ASSERT_NOT_REACHED();
3418     return TextEmphasisMark::None;
3419 }
3420
3421 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextOrientation e)
3422     : CSSValue(PrimitiveClass)
3423 {
3424     m_primitiveUnitType = CSS_VALUE_ID;
3425     switch (e) {
3426     case TextOrientation::Sideways:
3427         m_value.valueID = CSSValueSideways;
3428         break;
3429     case TextOrientation::Mixed:
3430         m_value.valueID = CSSValueMixed;
3431         break;
3432     case TextOrientation::Upright:
3433         m_value.valueID = CSSValueUpright;
3434         break;
3435     }
3436 }
3437
3438 template<> inline CSSPrimitiveValue::operator TextOrientation() const
3439 {
3440     ASSERT(isValueID());
3441
3442     switch (m_value.valueID) {
3443     case CSSValueSideways:
3444         return TextOrientation::Sideways;
3445     case CSSValueSidewaysRight:
3446         return TextOrientation::Sideways;
3447     case CSSValueVerticalRight:
3448         return TextOrientation::Mixed;
3449     case CSSValueMixed:
3450         return TextOrientation::Mixed;
3451     case CSSValueUpright:
3452         return TextOrientation::Upright;
3453     default:
3454         break;
3455     }
3456
3457     ASSERT_NOT_REACHED();
3458     return TextOrientation::Mixed;
3459 }
3460
3461 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(PointerEvents e)
3462     : CSSValue(PrimitiveClass)
3463 {
3464     m_primitiveUnitType = CSS_VALUE_ID;
3465     switch (e) {
3466     case PointerEvents::None:
3467         m_value.valueID = CSSValueNone;
3468         break;
3469     case PointerEvents::Stroke:
3470         m_value.valueID = CSSValueStroke;
3471         break;
3472     case PointerEvents::Fill:
3473         m_value.valueID = CSSValueFill;
3474         break;
3475     case PointerEvents::Painted:
3476         m_value.valueID = CSSValuePainted;
3477         break;
3478     case PointerEvents::Visible:
3479         m_value.valueID = CSSValueVisible;
3480         break;
3481     case PointerEvents::VisibleStroke:
3482         m_value.valueID = CSSValueVisibleStroke;
3483         break;
3484     case PointerEvents::VisibleFill:
3485         m_value.valueID = CSSValueVisibleFill;
3486         break;
3487     case PointerEvents::VisiblePainted:
3488         m_value.valueID = CSSValueVisiblePainted;
3489         break;
3490     case PointerEvents::Auto:
3491         m_value.valueID = CSSValueAuto;
3492         break;
3493     case PointerEvents::All:
3494         m_value.valueID = CSSValueAll;
3495         break;
3496     }
3497 }
3498
3499 template<> inline CSSPrimitiveValue::operator PointerEvents() const
3500 {
3501     ASSERT(isValueID());
3502
3503     switch (m_value.valueID) {
3504     case CSSValueAll:
3505         return PointerEvents::All;
3506     case CSSValueAuto:
3507         return PointerEvents::Auto;
3508     case CSSValueNone:
3509         return PointerEvents::None;
3510     case CSSValueVisiblePainted:
3511         return PointerEvents::VisiblePainted;
3512     case CSSValueVisibleFill:
3513         return PointerEvents::VisibleFill;
3514     case CSSValueVisibleStroke:
3515         return PointerEvents::VisibleStroke;
3516     case CSSValueVisible:
3517         return PointerEvents::Visible;
3518     case CSSValuePainted:
3519         return PointerEvents::Painted;
3520     case CSSValueFill:
3521         return PointerEvents::Fill;
3522     case CSSValueStroke:
3523         return PointerEvents::Stroke;
3524     default:
3525         break;
3526     }
3527
3528     ASSERT_NOT_REACHED();
3529     return PointerEvents::All;
3530 }
3531
3532 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Kerning kerning)
3533     : CSSValue(PrimitiveClass)
3534 {
3535     m_primitiveUnitType = CSS_VALUE_ID;
3536     switch (kerning) {
3537     case Kerning::Auto:
3538         m_value.valueID = CSSValueAuto;
3539         return;
3540     case Kerning::Normal:
3541         m_value.valueID = CSSValueNormal;
3542         return;
3543     case Kerning::NoShift:
3544         m_value.valueID = CSSValueNone;
3545         return;
3546     }
3547
3548     ASSERT_NOT_REACHED();
3549     m_value.valueID = CSSValueAuto;
3550 }
3551
3552 template<> inline CSSPrimitiveValue::operator Kerning() const
3553 {
3554     ASSERT(isValueID());
3555
3556     switch (m_value.valueID) {
3557     case CSSValueAuto:
3558         return Kerning::Auto;
3559     case CSSValueNormal:
3560         return Kerning::Normal;
3561     case CSSValueNone:
3562         return Kerning::NoShift;
3563     default:
3564         break;
3565     }
3566
3567     ASSERT_NOT_REACHED();
3568     return Kerning::Auto;
3569 }
3570
3571 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ObjectFit fit)
3572     : CSSValue(PrimitiveClass)
3573 {
3574     m_primitiveUnitType = CSS_VALUE_ID;
3575     switch (fit) {
3576     case ObjectFit::Fill:
3577         m_value.valueID = CSSValueFill;
3578         break;
3579     case ObjectFit::Contain:
3580