Remove support for -apple-trailing-word
[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 = CSSValueWebkitSticky;
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 CSSValueWebkitSticky:
2357         return PositionType::Sticky;
2358     default:
2359         break;
2360     }
2361
2362     ASSERT_NOT_REACHED();
2363     return PositionType::Static;
2364 }
2365
2366 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Resize e)
2367     : CSSValue(PrimitiveClass)
2368 {
2369     m_primitiveUnitType = CSS_VALUE_ID;
2370     switch (e) {
2371     case Resize::Both:
2372         m_value.valueID = CSSValueBoth;
2373         break;
2374     case Resize::Horizontal:
2375         m_value.valueID = CSSValueHorizontal;
2376         break;
2377     case Resize::Vertical:
2378         m_value.valueID = CSSValueVertical;
2379         break;
2380     case Resize::None:
2381         m_value.valueID = CSSValueNone;
2382         break;
2383     }
2384 }
2385
2386 template<> inline CSSPrimitiveValue::operator Resize() const
2387 {
2388     ASSERT(isValueID());
2389
2390     switch (m_value.valueID) {
2391     case CSSValueBoth:
2392         return Resize::Both;
2393     case CSSValueHorizontal:
2394         return Resize::Horizontal;
2395     case CSSValueVertical:
2396         return Resize::Vertical;
2397     case CSSValueAuto:
2398         ASSERT_NOT_REACHED(); // Depends on settings, thus should be handled by the caller.
2399         return Resize::None;
2400     case CSSValueNone:
2401         return Resize::None;
2402     default:
2403         break;
2404     }
2405
2406     ASSERT_NOT_REACHED();
2407     return Resize::None;
2408 }
2409
2410 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TableLayoutType e)
2411     : CSSValue(PrimitiveClass)
2412 {
2413     m_primitiveUnitType = CSS_VALUE_ID;
2414     switch (e) {
2415     case TableLayoutType::Auto:
2416         m_value.valueID = CSSValueAuto;
2417         break;
2418     case TableLayoutType::Fixed:
2419         m_value.valueID = CSSValueFixed;
2420         break;
2421     }
2422 }
2423
2424 template<> inline CSSPrimitiveValue::operator TableLayoutType() const
2425 {
2426     ASSERT(isValueID());
2427
2428     switch (m_value.valueID) {
2429     case CSSValueFixed:
2430         return TableLayoutType::Fixed;
2431     case CSSValueAuto:
2432         return TableLayoutType::Auto;
2433     default:
2434         break;
2435     }
2436
2437     ASSERT_NOT_REACHED();
2438     return TableLayoutType::Auto;
2439 }
2440
2441 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextAlignMode e)
2442     : CSSValue(PrimitiveClass)
2443 {
2444     m_primitiveUnitType = CSS_VALUE_ID;
2445     switch (e) {
2446     case TextAlignMode::Start:
2447         m_value.valueID = CSSValueStart;
2448         break;
2449     case TextAlignMode::End:
2450         m_value.valueID = CSSValueEnd;
2451         break;
2452     case TextAlignMode::Left:
2453         m_value.valueID = CSSValueLeft;
2454         break;
2455     case TextAlignMode::Right:
2456         m_value.valueID = CSSValueRight;
2457         break;
2458     case TextAlignMode::Center:
2459         m_value.valueID = CSSValueCenter;
2460         break;
2461     case TextAlignMode::Justify:
2462         m_value.valueID = CSSValueJustify;
2463         break;
2464     case TextAlignMode::WebKitLeft:
2465         m_value.valueID = CSSValueWebkitLeft;
2466         break;
2467     case TextAlignMode::WebKitRight:
2468         m_value.valueID = CSSValueWebkitRight;
2469         break;
2470     case TextAlignMode::WebKitCenter:
2471         m_value.valueID = CSSValueWebkitCenter;
2472         break;
2473     }
2474 }
2475
2476 template<> inline CSSPrimitiveValue::operator TextAlignMode() const
2477 {
2478     ASSERT(isValueID());
2479
2480     switch (m_value.valueID) {
2481     case CSSValueWebkitAuto: // Legacy -webkit-auto. Eqiuvalent to start.
2482     case CSSValueStart:
2483         return TextAlignMode::Start;
2484     case CSSValueEnd:
2485         return TextAlignMode::End;
2486     default:
2487         return static_cast<TextAlignMode>(m_value.valueID - CSSValueLeft);
2488     }
2489 }
2490
2491 #if ENABLE(CSS3_TEXT)
2492 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextAlignLast e)
2493     : CSSValue(PrimitiveClass)
2494 {
2495     m_primitiveUnitType = CSS_VALUE_ID;
2496     switch (e) {
2497     case TextAlignLast::Start:
2498         m_value.valueID = CSSValueStart;
2499         break;
2500     case TextAlignLast::End:
2501         m_value.valueID = CSSValueEnd;
2502         break;
2503     case TextAlignLast::Left:
2504         m_value.valueID = CSSValueLeft;
2505         break;
2506     case TextAlignLast::Right:
2507         m_value.valueID = CSSValueRight;
2508         break;
2509     case TextAlignLast::Center:
2510         m_value.valueID = CSSValueCenter;
2511         break;
2512     case TextAlignLast::Justify:
2513         m_value.valueID = CSSValueJustify;
2514         break;
2515     case TextAlignLast::Auto:
2516         m_value.valueID = CSSValueAuto;
2517         break;
2518     }
2519 }
2520
2521 template<> inline CSSPrimitiveValue::operator TextAlignLast() const
2522 {
2523     ASSERT(isValueID());
2524
2525     switch (m_value.valueID) {
2526     case CSSValueAuto:
2527         return TextAlignLast::Auto;
2528     case CSSValueStart:
2529         return TextAlignLast::Start;
2530     case CSSValueEnd:
2531         return TextAlignLast::End;
2532     case CSSValueLeft:
2533         return TextAlignLast::Left;
2534     case CSSValueRight:
2535         return TextAlignLast::Right;
2536     case CSSValueCenter:
2537         return TextAlignLast::Center;
2538     case CSSValueJustify:
2539         return TextAlignLast::Justify;
2540     default:
2541         break;
2542     }
2543
2544     ASSERT_NOT_REACHED();
2545     return TextAlignLast::Auto;
2546 }
2547
2548 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextJustify e)
2549     : CSSValue(PrimitiveClass)
2550 {
2551     m_primitiveUnitType = CSS_VALUE_ID;
2552     switch (e) {
2553     case TextJustify::Auto:
2554         m_value.valueID = CSSValueAuto;
2555         break;
2556     case TextJustify::None:
2557         m_value.valueID = CSSValueNone;
2558         break;
2559     case TextJustify::InterWord:
2560         m_value.valueID = CSSValueInterWord;
2561         break;
2562     case TextJustify::Distribute:
2563         m_value.valueID = CSSValueDistribute;
2564         break;
2565     }
2566 }
2567
2568 template<> inline CSSPrimitiveValue::operator TextJustify() const
2569 {
2570     ASSERT(isValueID());
2571
2572     switch (m_value.valueID) {
2573     case CSSValueAuto:
2574         return TextJustify::Auto;
2575     case CSSValueNone:
2576         return TextJustify::None;
2577     case CSSValueInterWord:
2578         return TextJustify::InterWord;
2579     case CSSValueDistribute:
2580         return TextJustify::Distribute;
2581     default:
2582         break;
2583     }
2584
2585     ASSERT_NOT_REACHED();
2586     return TextJustify::Auto;
2587 }
2588 #endif // CSS3_TEXT
2589
2590 template<> inline CSSPrimitiveValue::operator OptionSet<TextDecoration>() const
2591 {
2592     ASSERT(isValueID());
2593
2594     switch (m_value.valueID) {
2595     case CSSValueNone:
2596         return OptionSet<TextDecoration> { };
2597     case CSSValueUnderline:
2598         return TextDecoration::Underline;
2599     case CSSValueOverline:
2600         return TextDecoration::Overline;
2601     case CSSValueLineThrough:
2602         return TextDecoration::LineThrough;
2603     case CSSValueBlink:
2604         return TextDecoration::Blink;
2605 #if ENABLE(LETTERPRESS)
2606     case CSSValueWebkitLetterpress:
2607         return TextDecoration::Letterpress;
2608 #endif
2609     default:
2610         break;
2611     }
2612
2613     ASSERT_NOT_REACHED();
2614     return OptionSet<TextDecoration> { };
2615 }
2616
2617 template<> inline CSSPrimitiveValue::operator TextDecorationStyle() const
2618 {
2619     ASSERT(isValueID());
2620
2621     switch (m_value.valueID) {
2622     case CSSValueSolid:
2623         return TextDecorationStyle::Solid;
2624     case CSSValueDouble:
2625         return TextDecorationStyle::Double;
2626     case CSSValueDotted:
2627         return TextDecorationStyle::Dotted;
2628     case CSSValueDashed:
2629         return TextDecorationStyle::Dashed;
2630     case CSSValueWavy:
2631         return TextDecorationStyle::Wavy;
2632     default:
2633         break;
2634     }
2635
2636     ASSERT_NOT_REACHED();
2637     return TextDecorationStyle::Solid;
2638 }
2639
2640 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextUnderlinePosition position)
2641     : CSSValue(PrimitiveClass)
2642 {
2643     m_primitiveUnitType = CSS_VALUE_ID;
2644     switch (position) {
2645     case TextUnderlinePosition::Auto:
2646         m_value.valueID = CSSValueAuto;
2647         break;
2648     case TextUnderlinePosition::Under:
2649         m_value.valueID = CSSValueUnder;
2650         break;
2651     case TextUnderlinePosition::FromFont:
2652         m_value.valueID = CSSValueFromFont;
2653         break;
2654     }
2655
2656     // FIXME: Implement support for 'under left' and 'under right' values.
2657 }
2658
2659 template<> inline CSSPrimitiveValue::operator TextUnderlinePosition() const
2660 {
2661     ASSERT(isValueID());
2662
2663     switch (m_value.valueID) {
2664     case CSSValueAuto:
2665         return TextUnderlinePosition::Auto;
2666     case CSSValueUnder:
2667         return TextUnderlinePosition::Under;
2668     case CSSValueFromFont:
2669         return TextUnderlinePosition::FromFont;
2670     default:
2671         break;
2672     }
2673
2674     // FIXME: Implement support for 'under left' and 'under right' values.
2675     ASSERT_NOT_REACHED();
2676     return TextUnderlinePosition::Auto;
2677 }
2678
2679 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextSecurity e)
2680     : CSSValue(PrimitiveClass)
2681 {
2682     m_primitiveUnitType = CSS_VALUE_ID;
2683     switch (e) {
2684     case TextSecurity::None:
2685         m_value.valueID = CSSValueNone;
2686         break;
2687     case TextSecurity::Disc:
2688         m_value.valueID = CSSValueDisc;
2689         break;
2690     case TextSecurity::Circle:
2691         m_value.valueID = CSSValueCircle;
2692         break;
2693     case TextSecurity::Square:
2694         m_value.valueID = CSSValueSquare;
2695         break;
2696     }
2697 }
2698
2699 template<> inline CSSPrimitiveValue::operator TextSecurity() const
2700 {
2701     ASSERT(isValueID());
2702
2703     switch (m_value.valueID) {
2704     case CSSValueNone:
2705         return TextSecurity::None;
2706     case CSSValueDisc:
2707         return TextSecurity::Disc;
2708     case CSSValueCircle:
2709         return TextSecurity::Circle;
2710     case CSSValueSquare:
2711         return TextSecurity::Square;
2712     default:
2713         break;
2714     }
2715
2716     ASSERT_NOT_REACHED();
2717     return TextSecurity::None;
2718 }
2719
2720 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextTransform e)
2721     : CSSValue(PrimitiveClass)
2722 {
2723     m_primitiveUnitType = CSS_VALUE_ID;
2724     switch (e) {
2725     case TextTransform::Capitalize:
2726         m_value.valueID = CSSValueCapitalize;
2727         break;
2728     case TextTransform::Uppercase:
2729         m_value.valueID = CSSValueUppercase;
2730         break;
2731     case TextTransform::Lowercase:
2732         m_value.valueID = CSSValueLowercase;
2733         break;
2734     case TextTransform::None:
2735         m_value.valueID = CSSValueNone;
2736         break;
2737     }
2738 }
2739
2740 template<> inline CSSPrimitiveValue::operator TextTransform() const
2741 {
2742     ASSERT(isValueID());
2743
2744     switch (m_value.valueID) {
2745     case CSSValueCapitalize:
2746         return TextTransform::Capitalize;
2747     case CSSValueUppercase:
2748         return TextTransform::Uppercase;
2749     case CSSValueLowercase:
2750         return TextTransform::Lowercase;
2751     case CSSValueNone:
2752         return TextTransform::None;
2753     default:
2754         break;
2755     }
2756
2757     ASSERT_NOT_REACHED();
2758     return TextTransform::None;
2759 }
2760
2761 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EUnicodeBidi e)
2762     : CSSValue(PrimitiveClass)
2763 {
2764     m_primitiveUnitType = CSS_VALUE_ID;
2765     switch (e) {
2766     case UBNormal:
2767         m_value.valueID = CSSValueNormal;
2768         break;
2769     case Embed:
2770         m_value.valueID = CSSValueEmbed;
2771         break;
2772     case Override:
2773         m_value.valueID = CSSValueBidiOverride;
2774         break;
2775     case Isolate:
2776         m_value.valueID = CSSValueIsolate;
2777         break;
2778     case IsolateOverride:
2779         m_value.valueID = CSSValueIsolateOverride;
2780         break;
2781     case Plaintext:
2782         m_value.valueID = CSSValuePlaintext;
2783         break;
2784     }
2785 }
2786
2787 template<> inline CSSPrimitiveValue::operator EUnicodeBidi() const
2788 {
2789     ASSERT(isValueID());
2790
2791     switch (m_value.valueID) {
2792     case CSSValueNormal:
2793         return UBNormal;
2794     case CSSValueEmbed:
2795         return Embed;
2796     case CSSValueBidiOverride:
2797         return Override;
2798     case CSSValueIsolate:
2799     case CSSValueWebkitIsolate:
2800         return Isolate;
2801     case CSSValueIsolateOverride:
2802     case CSSValueWebkitIsolateOverride:
2803         return IsolateOverride;
2804     case CSSValuePlaintext:
2805     case CSSValueWebkitPlaintext:
2806         return Plaintext;
2807     default:
2808         break;
2809     }
2810
2811     ASSERT_NOT_REACHED();
2812     return UBNormal;
2813 }
2814
2815 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserDrag e)
2816     : CSSValue(PrimitiveClass)
2817 {
2818     m_primitiveUnitType = CSS_VALUE_ID;
2819     switch (e) {
2820     case UserDrag::Auto:
2821         m_value.valueID = CSSValueAuto;
2822         break;
2823     case UserDrag::None:
2824         m_value.valueID = CSSValueNone;
2825         break;
2826     case UserDrag::Element:
2827         m_value.valueID = CSSValueElement;
2828         break;
2829     default:
2830         break;
2831     }
2832 }
2833
2834 template<> inline CSSPrimitiveValue::operator UserDrag() const
2835 {
2836     ASSERT(isValueID());
2837
2838     switch (m_value.valueID) {
2839     case CSSValueAuto:
2840         return UserDrag::Auto;
2841     case CSSValueNone:
2842         return UserDrag::None;
2843     case CSSValueElement:
2844         return UserDrag::Element;
2845     default:
2846         break;
2847     }
2848
2849     ASSERT_NOT_REACHED();
2850     return UserDrag::Auto;
2851 }
2852
2853 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserModify e)
2854     : CSSValue(PrimitiveClass)
2855 {
2856     m_primitiveUnitType = CSS_VALUE_ID;
2857     switch (e) {
2858     case UserModify::ReadOnly:
2859         m_value.valueID = CSSValueReadOnly;
2860         break;
2861     case UserModify::ReadWrite:
2862         m_value.valueID = CSSValueReadWrite;
2863         break;
2864     case UserModify::ReadWritePlaintextOnly:
2865         m_value.valueID = CSSValueReadWritePlaintextOnly;
2866         break;
2867     }
2868 }
2869
2870 template<> inline CSSPrimitiveValue::operator UserModify() const
2871 {
2872     ASSERT(isValueID());
2873
2874     switch (m_value.valueID) {
2875     case CSSValueReadOnly:
2876         return UserModify::ReadOnly;
2877     case CSSValueReadWrite:
2878         return UserModify::ReadWrite;
2879     case CSSValueReadWritePlaintextOnly:
2880         return UserModify::ReadWritePlaintextOnly;
2881     default:
2882         break;
2883     }
2884
2885     ASSERT_NOT_REACHED();
2886     return UserModify::ReadOnly;
2887 }
2888
2889 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(UserSelect e)
2890     : CSSValue(PrimitiveClass)
2891 {
2892     m_primitiveUnitType = CSS_VALUE_ID;
2893     switch (e) {
2894     case UserSelect::None:
2895         m_value.valueID = CSSValueNone;
2896         break;
2897     case UserSelect::Text:
2898         m_value.valueID = CSSValueText;
2899         break;
2900     case UserSelect::All:
2901         m_value.valueID = CSSValueAll;
2902         break;
2903     }
2904 }
2905
2906 template<> inline CSSPrimitiveValue::operator UserSelect() const
2907 {
2908     ASSERT(isValueID());
2909
2910     switch (m_value.valueID) {
2911     case CSSValueAuto:
2912         return UserSelect::Text;
2913     case CSSValueNone:
2914         return UserSelect::None;
2915     case CSSValueText:
2916         return UserSelect::Text;
2917     case CSSValueAll:
2918         return UserSelect::All;
2919     default:
2920         break;
2921     }
2922
2923     ASSERT_NOT_REACHED();
2924     return UserSelect::Text;
2925 }
2926
2927 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(VerticalAlign a)
2928     : CSSValue(PrimitiveClass)
2929 {
2930     m_primitiveUnitType = CSS_VALUE_ID;
2931     switch (a) {
2932     case VerticalAlign::Top:
2933         m_value.valueID = CSSValueTop;
2934         break;
2935     case VerticalAlign::Bottom:
2936         m_value.valueID = CSSValueBottom;
2937         break;
2938     case VerticalAlign::Middle:
2939         m_value.valueID = CSSValueMiddle;
2940         break;
2941     case VerticalAlign::Baseline:
2942         m_value.valueID = CSSValueBaseline;
2943         break;
2944     case VerticalAlign::TextBottom:
2945         m_value.valueID = CSSValueTextBottom;
2946         break;
2947     case VerticalAlign::TextTop:
2948         m_value.valueID = CSSValueTextTop;
2949         break;
2950     case VerticalAlign::Sub:
2951         m_value.valueID = CSSValueSub;
2952         break;
2953     case VerticalAlign::Super:
2954         m_value.valueID = CSSValueSuper;
2955         break;
2956     case VerticalAlign::BaselineMiddle:
2957         m_value.valueID = CSSValueWebkitBaselineMiddle;
2958         break;
2959     case VerticalAlign::Length:
2960         m_value.valueID = CSSValueInvalid;
2961     }
2962 }
2963
2964 template<> inline CSSPrimitiveValue::operator VerticalAlign() const
2965 {
2966     ASSERT(isValueID());
2967
2968     switch (m_value.valueID) {
2969     case CSSValueTop:
2970         return VerticalAlign::Top;
2971     case CSSValueBottom:
2972         return VerticalAlign::Bottom;
2973     case CSSValueMiddle:
2974         return VerticalAlign::Middle;
2975     case CSSValueBaseline:
2976         return VerticalAlign::Baseline;
2977     case CSSValueTextBottom:
2978         return VerticalAlign::TextBottom;
2979     case CSSValueTextTop:
2980         return VerticalAlign::TextTop;
2981     case CSSValueSub:
2982         return VerticalAlign::Sub;
2983     case CSSValueSuper:
2984         return VerticalAlign::Super;
2985     case CSSValueWebkitBaselineMiddle:
2986         return VerticalAlign::BaselineMiddle;
2987     default:
2988         break;
2989     }
2990
2991     ASSERT_NOT_REACHED();
2992     return VerticalAlign::Top;
2993 }
2994
2995 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Visibility e)
2996     : CSSValue(PrimitiveClass)
2997 {
2998     m_primitiveUnitType = CSS_VALUE_ID;
2999     switch (e) {
3000     case Visibility::Visible:
3001         m_value.valueID = CSSValueVisible;
3002         break;
3003     case Visibility::Hidden:
3004         m_value.valueID = CSSValueHidden;
3005         break;
3006     case Visibility::Collapse:
3007         m_value.valueID = CSSValueCollapse;
3008         break;
3009     }
3010 }
3011
3012 template<> inline CSSPrimitiveValue::operator Visibility() const
3013 {
3014     ASSERT(isValueID());
3015
3016     switch (m_value.valueID) {
3017     case CSSValueHidden:
3018         return Visibility::Hidden;
3019     case CSSValueVisible:
3020         return Visibility::Visible;
3021     case CSSValueCollapse:
3022         return Visibility::Collapse;
3023     default:
3024         break;
3025     }
3026
3027     ASSERT_NOT_REACHED();
3028     return Visibility::Visible;
3029 }
3030
3031 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WhiteSpace e)
3032     : CSSValue(PrimitiveClass)
3033 {
3034     m_primitiveUnitType = CSS_VALUE_ID;
3035     switch (e) {
3036     case WhiteSpace::Normal:
3037         m_value.valueID = CSSValueNormal;
3038         break;
3039     case WhiteSpace::Pre:
3040         m_value.valueID = CSSValuePre;
3041         break;
3042     case WhiteSpace::PreWrap:
3043         m_value.valueID = CSSValuePreWrap;
3044         break;
3045     case WhiteSpace::PreLine:
3046         m_value.valueID = CSSValuePreLine;
3047         break;
3048     case WhiteSpace::NoWrap:
3049         m_value.valueID = CSSValueNowrap;
3050         break;
3051     case WhiteSpace::KHTMLNoWrap:
3052         m_value.valueID = CSSValueWebkitNowrap;
3053         break;
3054     }
3055 }
3056
3057 template<> inline CSSPrimitiveValue::operator WhiteSpace() const
3058 {
3059     ASSERT(isValueID());
3060
3061     switch (m_value.valueID) {
3062     case CSSValueWebkitNowrap:
3063         return WhiteSpace::KHTMLNoWrap;
3064     case CSSValueNowrap:
3065         return WhiteSpace::NoWrap;
3066     case CSSValuePre:
3067         return WhiteSpace::Pre;
3068     case CSSValuePreWrap:
3069         return WhiteSpace::PreWrap;
3070     case CSSValuePreLine:
3071         return WhiteSpace::PreLine;
3072     case CSSValueNormal:
3073         return WhiteSpace::Normal;
3074     default:
3075         break;
3076     }
3077
3078     ASSERT_NOT_REACHED();
3079     return WhiteSpace::Normal;
3080 }
3081
3082 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WordBreak e)
3083     : CSSValue(PrimitiveClass)
3084 {
3085     m_primitiveUnitType = CSS_VALUE_ID;
3086     switch (e) {
3087     case WordBreak::Normal:
3088         m_value.valueID = CSSValueNormal;
3089         break;
3090     case WordBreak::BreakAll:
3091         m_value.valueID = CSSValueBreakAll;
3092         break;
3093     case WordBreak::KeepAll:
3094         m_value.valueID = CSSValueKeepAll;
3095         break;
3096     case WordBreak::BreakWord:
3097         m_value.valueID = CSSValueBreakWord;
3098         break;
3099     }
3100 }
3101
3102 template<> inline CSSPrimitiveValue::operator WordBreak() const
3103 {
3104     ASSERT(isValueID());
3105
3106     switch (m_value.valueID) {
3107     case CSSValueBreakAll:
3108         return WordBreak::BreakAll;
3109     case CSSValueKeepAll:
3110         return WordBreak::KeepAll;
3111     case CSSValueBreakWord:
3112         return WordBreak::BreakWord;
3113     case CSSValueNormal:
3114         return WordBreak::Normal;
3115     default:
3116         break;
3117     }
3118
3119     ASSERT_NOT_REACHED();
3120     return WordBreak::Normal;
3121 }
3122
3123 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(OverflowWrap e)
3124     : CSSValue(PrimitiveClass)
3125 {
3126     m_primitiveUnitType = CSS_VALUE_ID;
3127     switch (e) {
3128     case OverflowWrap::Normal:
3129         m_value.valueID = CSSValueNormal;
3130         break;
3131     case OverflowWrap::Break:
3132         m_value.valueID = CSSValueBreakWord;
3133         break;
3134     }
3135 }
3136
3137 template<> inline CSSPrimitiveValue::operator OverflowWrap() const
3138 {
3139     ASSERT(isValueID());
3140
3141     switch (m_value.valueID) {
3142     case CSSValueBreakWord:
3143         return OverflowWrap::Break;
3144     case CSSValueNormal:
3145         return OverflowWrap::Normal;
3146     default:
3147         break;
3148     }
3149
3150     ASSERT_NOT_REACHED();
3151     return OverflowWrap::Normal;
3152 }
3153
3154 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextDirection e)
3155     : CSSValue(PrimitiveClass)
3156 {
3157     m_primitiveUnitType = CSS_VALUE_ID;
3158     switch (e) {
3159     case TextDirection::LTR:
3160         m_value.valueID = CSSValueLtr;
3161         break;
3162     case TextDirection::RTL:
3163         m_value.valueID = CSSValueRtl;
3164         break;
3165     }
3166 }
3167
3168 template<> inline CSSPrimitiveValue::operator TextDirection() const
3169 {
3170     ASSERT(isValueID());
3171
3172     switch (m_value.valueID) {
3173     case CSSValueLtr:
3174         return TextDirection::LTR;
3175     case CSSValueRtl:
3176         return TextDirection::RTL;
3177     default:
3178         break;
3179     }
3180
3181     ASSERT_NOT_REACHED();
3182     return TextDirection::LTR;
3183 }
3184
3185 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WritingMode e)
3186     : CSSValue(PrimitiveClass)
3187 {
3188     m_primitiveUnitType = CSS_VALUE_ID;
3189     switch (e) {
3190     case TopToBottomWritingMode:
3191         m_value.valueID = CSSValueHorizontalTb;
3192         break;
3193     case RightToLeftWritingMode:
3194         m_value.valueID = CSSValueVerticalRl;
3195         break;
3196     case LeftToRightWritingMode:
3197         m_value.valueID = CSSValueVerticalLr;
3198         break;
3199     case BottomToTopWritingMode:
3200         m_value.valueID = CSSValueHorizontalBt;
3201         break;
3202     }
3203 }
3204
3205 template<> inline CSSPrimitiveValue::operator WritingMode() const
3206 {
3207     ASSERT(isValueID());
3208
3209     switch (m_value.valueID) {
3210     case CSSValueHorizontalTb:
3211     case CSSValueLr:
3212     case CSSValueLrTb:
3213     case CSSValueRl:
3214     case CSSValueRlTb:
3215         return TopToBottomWritingMode;
3216     case CSSValueVerticalRl:
3217     case CSSValueTb:
3218     case CSSValueTbRl:
3219         return RightToLeftWritingMode;
3220     case CSSValueVerticalLr:
3221         return LeftToRightWritingMode;
3222     case CSSValueHorizontalBt:
3223         return BottomToTopWritingMode;
3224     default:
3225         break;
3226     }
3227
3228     ASSERT_NOT_REACHED();
3229     return TopToBottomWritingMode;
3230 }
3231
3232 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextCombine e)
3233     : CSSValue(PrimitiveClass)
3234 {
3235     m_primitiveUnitType = CSS_VALUE_ID;
3236     switch (e) {
3237     case TextCombine::None:
3238         m_value.valueID = CSSValueNone;
3239         break;
3240     case TextCombine::Horizontal:
3241         m_value.valueID = CSSValueHorizontal;
3242         break;
3243     }
3244 }
3245
3246 template<> inline CSSPrimitiveValue::operator TextCombine() const
3247 {
3248     ASSERT(isValueID());
3249
3250     switch (m_value.valueID) {
3251     case CSSValueNone:
3252         return TextCombine::None;
3253     case CSSValueHorizontal:
3254         return TextCombine::Horizontal;
3255     default:
3256         break;
3257     }
3258
3259     ASSERT_NOT_REACHED();
3260     return TextCombine::None;
3261 }
3262
3263 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(RubyPosition position)
3264     : CSSValue(PrimitiveClass)
3265 {
3266     m_primitiveUnitType = CSS_VALUE_ID;
3267     switch (position) {
3268     case RubyPosition::Before:
3269         m_value.valueID = CSSValueBefore;
3270         break;
3271     case RubyPosition::After:
3272         m_value.valueID = CSSValueAfter;
3273         break;
3274     case RubyPosition::InterCharacter:
3275         m_value.valueID = CSSValueInterCharacter;
3276         break;
3277     }
3278 }
3279
3280 template<> inline CSSPrimitiveValue::operator RubyPosition() const
3281 {
3282     ASSERT(isValueID());
3283
3284     switch (m_value.valueID) {
3285     case CSSValueBefore:
3286         return RubyPosition::Before;
3287     case CSSValueAfter:
3288         return RubyPosition::After;
3289     case CSSValueInterCharacter:
3290         return RubyPosition::InterCharacter;
3291     default:
3292         break;
3293     }
3294
3295     ASSERT_NOT_REACHED();
3296     return RubyPosition::Before;
3297 }
3298
3299 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextOverflow overflow)
3300     : CSSValue(PrimitiveClass)
3301 {
3302     m_primitiveUnitType = CSS_VALUE_ID;
3303     switch (overflow) {
3304     case TextOverflow::Clip:
3305         m_value.valueID = CSSValueClip;
3306         break;
3307     case TextOverflow::Ellipsis:
3308         m_value.valueID = CSSValueEllipsis;
3309         break;
3310     }
3311 }
3312
3313 template<> inline CSSPrimitiveValue::operator TextOverflow() const
3314 {
3315     ASSERT(isValueID());
3316
3317     switch (m_value.valueID) {
3318     case CSSValueClip:
3319         return TextOverflow::Clip;
3320     case CSSValueEllipsis:
3321         return TextOverflow::Ellipsis;
3322     default:
3323         break;
3324     }
3325
3326     ASSERT_NOT_REACHED();
3327     return TextOverflow::Clip;
3328 }
3329
3330 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisFill fill)
3331     : CSSValue(PrimitiveClass)
3332 {
3333     m_primitiveUnitType = CSS_VALUE_ID;
3334     switch (fill) {
3335     case TextEmphasisFill::Filled:
3336         m_value.valueID = CSSValueFilled;
3337         break;
3338     case TextEmphasisFill::Open:
3339         m_value.valueID = CSSValueOpen;
3340         break;
3341     }
3342 }
3343
3344 template<> inline CSSPrimitiveValue::operator TextEmphasisFill() const
3345 {
3346     ASSERT(isValueID());
3347
3348     switch (m_value.valueID) {
3349     case CSSValueFilled:
3350         return TextEmphasisFill::Filled;
3351     case CSSValueOpen:
3352         return TextEmphasisFill::Open;
3353     default:
3354         break;
3355     }
3356
3357     ASSERT_NOT_REACHED();
3358     return TextEmphasisFill::Filled;
3359 }
3360
3361 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextEmphasisMark mark)
3362     : CSSValue(PrimitiveClass)
3363 {
3364     m_primitiveUnitType = CSS_VALUE_ID;
3365     switch (mark) {
3366     case TextEmphasisMark::Dot:
3367         m_value.valueID = CSSValueDot;
3368         break;
3369     case TextEmphasisMark::Circle:
3370         m_value.valueID = CSSValueCircle;
3371         break;
3372     case TextEmphasisMark::DoubleCircle:
3373         m_value.valueID = CSSValueDoubleCircle;
3374         break;
3375     case TextEmphasisMark::Triangle:
3376         m_value.valueID = CSSValueTriangle;
3377         break;
3378     case TextEmphasisMark::Sesame:
3379         m_value.valueID = CSSValueSesame;
3380         break;
3381     case TextEmphasisMark::None:
3382     case TextEmphasisMark::Auto:
3383     case TextEmphasisMark::Custom:
3384         ASSERT_NOT_REACHED();
3385         m_value.valueID = CSSValueNone;
3386         break;
3387     }
3388 }
3389
3390 template<> inline CSSPrimitiveValue::operator TextEmphasisMark() const
3391 {
3392     ASSERT(isValueID());
3393
3394     switch (m_value.valueID) {
3395     case CSSValueNone:
3396         return TextEmphasisMark::None;
3397     case CSSValueDot:
3398         return TextEmphasisMark::Dot;
3399     case CSSValueCircle:
3400         return TextEmphasisMark::Circle;
3401     case CSSValueDoubleCircle:
3402         return TextEmphasisMark::DoubleCircle;
3403     case CSSValueTriangle:
3404         return TextEmphasisMark::Triangle;
3405     case CSSValueSesame:
3406         return TextEmphasisMark::Sesame;
3407     default:
3408         break;
3409     }
3410
3411     ASSERT_NOT_REACHED();
3412     return TextEmphasisMark::None;
3413 }
3414
3415 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextOrientation e)
3416     : CSSValue(PrimitiveClass)
3417 {
3418     m_primitiveUnitType = CSS_VALUE_ID;
3419     switch (e) {
3420     case TextOrientation::Sideways:
3421         m_value.valueID = CSSValueSideways;
3422         break;
3423     case TextOrientation::Mixed:
3424         m_value.valueID = CSSValueMixed;
3425         break;
3426     case TextOrientation::Upright:
3427         m_value.valueID = CSSValueUpright;
3428         break;
3429     }
3430 }
3431
3432 template<> inline CSSPrimitiveValue::operator TextOrientation() const
3433 {
3434     ASSERT(isValueID());
3435
3436     switch (m_value.valueID) {
3437     case CSSValueSideways:
3438         return TextOrientation::Sideways;
3439     case CSSValueSidewaysRight:
3440         return TextOrientation::Sideways;
3441     case CSSValueVerticalRight:
3442         return TextOrientation::Mixed;
3443     case CSSValueMixed:
3444         return TextOrientation::Mixed;
3445     case CSSValueUpright:
3446         return TextOrientation::Upright;
3447     default:
3448         break;
3449     }
3450
3451     ASSERT_NOT_REACHED();
3452     return TextOrientation::Mixed;
3453 }
3454
3455 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(PointerEvents e)
3456     : CSSValue(PrimitiveClass)
3457 {
3458     m_primitiveUnitType = CSS_VALUE_ID;
3459     switch (e) {
3460     case PointerEvents::None:
3461         m_value.valueID = CSSValueNone;
3462         break;
3463     case PointerEvents::Stroke:
3464         m_value.valueID = CSSValueStroke;
3465         break;
3466     case PointerEvents::Fill:
3467         m_value.valueID = CSSValueFill;
3468         break;
3469     case PointerEvents::Painted:
3470         m_value.valueID = CSSValuePainted;
3471         break;
3472     case PointerEvents::Visible:
3473         m_value.valueID = CSSValueVisible;
3474         break;
3475     case PointerEvents::VisibleStroke:
3476         m_value.valueID = CSSValueVisibleStroke;
3477         break;
3478     case PointerEvents::VisibleFill:
3479         m_value.valueID = CSSValueVisibleFill;
3480         break;
3481     case PointerEvents::VisiblePainted:
3482         m_value.valueID = CSSValueVisiblePainted;
3483         break;
3484     case PointerEvents::Auto:
3485         m_value.valueID = CSSValueAuto;
3486         break;
3487     case PointerEvents::All:
3488         m_value.valueID = CSSValueAll;
3489         break;
3490     }
3491 }
3492
3493 template<> inline CSSPrimitiveValue::operator PointerEvents() const
3494 {
3495     ASSERT(isValueID());
3496
3497     switch (m_value.valueID) {
3498     case CSSValueAll:
3499         return PointerEvents::All;
3500     case CSSValueAuto:
3501         return PointerEvents::Auto;
3502     case CSSValueNone:
3503         return PointerEvents::None;
3504     case CSSValueVisiblePainted:
3505         return PointerEvents::VisiblePainted;
3506     case CSSValueVisibleFill:
3507         return PointerEvents::VisibleFill;
3508     case CSSValueVisibleStroke:
3509         return PointerEvents::VisibleStroke;
3510     case CSSValueVisible:
3511         return PointerEvents::Visible;
3512     case CSSValuePainted:
3513         return PointerEvents::Painted;
3514     case CSSValueFill:
3515         return PointerEvents::Fill;
3516     case CSSValueStroke:
3517         return PointerEvents::Stroke;
3518     default:
3519         break;
3520     }
3521
3522     ASSERT_NOT_REACHED();
3523     return PointerEvents::All;
3524 }
3525
3526 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Kerning kerning)
3527     : CSSValue(PrimitiveClass)
3528 {
3529     m_primitiveUnitType = CSS_VALUE_ID;
3530     switch (kerning) {
3531     case Kerning::Auto:
3532         m_value.valueID = CSSValueAuto;
3533         return;
3534     case Kerning::Normal:
3535         m_value.valueID = CSSValueNormal;
3536         return;
3537     case Kerning::NoShift:
3538         m_value.valueID = CSSValueNone;
3539         return;
3540     }
3541
3542     ASSERT_NOT_REACHED();
3543     m_value.valueID = CSSValueAuto;
3544 }
3545
3546 template<> inline CSSPrimitiveValue::operator Kerning() const
3547 {
3548     ASSERT(isValueID());
3549
3550     switch (m_value.valueID) {
3551     case CSSValueAuto:
3552         return Kerning::Auto;
3553     case CSSValueNormal:
3554         return Kerning::Normal;
3555     case CSSValueNone:
3556         return Kerning::NoShift;
3557     default:
3558         break;
3559     }
3560
3561     ASSERT_NOT_REACHED();
3562     return Kerning::Auto;
3563 }
3564
3565 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ObjectFit fit)
3566     : CSSValue(PrimitiveClass)
3567 {
3568     m_primitiveUnitType = CSS_VALUE_ID;
3569     switch (fit) {
3570     case ObjectFit::Fill:
3571         m_value.valueID = CSSValueFill;
3572         break;
3573     case ObjectFit::Contain:
3574         m_value.valueID = CSSValueContain;
3575         break;
3576     case ObjectFit::Cover:
3577         m_value.valueID = CSSValueCover;
3578         break;
3579     case ObjectFit::None:
3580         m_value.valueID = CSSValueNone;
3581         break;
3582     case ObjectFit::ScaleDown:
3583         m_value.valueID = CSSValueScaleDown;
3584         break;
3585     }
3586 }
3587
3588 template<> inline CSSPrimitiveValue::operator ObjectFit() const
3589 {
3590     ASSERT(isValueID());
3591
3592     switch (m_value.valueID) {
3593     case CSSValueFill:
3594         return ObjectFit::Fill;
3595     case CSSValueContain:
3596         return ObjectFit::Contain;
3597     case CSSValueCover:
3598         return ObjectFit::Cover;
3599     case CSSValueNone:
3600         return ObjectFit::None;
3601     case CSSValueScaleDown:
3602         return ObjectFit::ScaleDown;
3603     default:
3604         ASSERT_NOT_REACHED();
3605         return ObjectFit::Fill;
3606     }
3607 }
3608
3609 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmoothingMode smoothing)
3610     : CSSValue(PrimitiveClass)
3611 {
3612     m_primitiveUnitType = CSS_VALUE_ID;
3613     switch (smoothing) {
3614     case FontSmoothingMode::AutoSmoothing:
3615         m_value.valueID = CSSValueAuto;
3616         return;
3617     case FontSmoothingMode::NoSmoothing:
3618         m_value.valueID = CSSValueNone;
3619         return;
3620     case FontSmoothingMode::Antialiased:
3621         m_value.valueID = CSSValueAntialiased;
3622         return;
3623     case FontSmoothingMode::SubpixelAntialiased:
3624         m_value.valueID = CSSValueSubpixelAntialiased;
3625         return;
3626     }
3627
3628     ASSERT_NOT_REACHED();
3629     m_value.valueID = CSSValueAuto;
3630 }
3631
3632 template<> inline CSSPrimitiveValue::operator FontSmoothingMode() const
3633 {
3634     ASSERT(isValueID());
3635
3636     switch (m_value.valueID) {
3637     case CSSValueAuto:
3638         return FontSmoothingMode::AutoSmoothing;
3639     case CSSValueNone:
3640         return FontSmoothingMode::NoSmoothing;
3641     case CSSValueAntialiased:
3642         return FontSmoothingMode::Antialiased;
3643     case CSSValueSubpixelAntialiased:
3644         return FontSmoothingMode::SubpixelAntialiased;
3645     default:
3646         break;
3647     }
3648
3649     ASSERT_NOT_REACHED();
3650     return FontSmoothingMode::AutoSmoothing;
3651 }
3652
3653 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmallCaps smallCaps)
3654     : CSSValue(PrimitiveClass)
3655 {
3656     m_primitiveUnitType = CSS_VALUE_ID;
3657     switch (smallCaps) {
3658     case FontSmallCaps::Off:
3659         m_value.valueID = CSSValueNormal;
3660         return;
3661     case FontSmallCaps::On:
3662         m_value.valueID = CSSValueSmallCaps;
3663         return;
3664     }
3665
3666     ASSERT_NOT_REACHED();
3667     m_value.valueID = CSSValueNormal;
3668 }
3669
3670 template<> inline CSSPrimitiveValue::operator FontSmallCaps() const
3671 {
3672     ASSERT(isValueID());
3673
3674     switch (m_value.valueID) {
3675     case CSSValueSmallCaps:
3676         return FontSmallCaps::On;
3677     case CSSValueNormal:
3678         return FontSmallCaps::Off;
3679     default:
3680         break;
3681     }
3682     ASSERT_NOT_REACHED();
3683     return FontSmallCaps::Off;
3684 }
3685
3686 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextRenderingMode e)
3687     : CSSValue(PrimitiveClass)
3688 {
3689     m_primitiveUnitType = CSS_VALUE_ID;
3690     switch (e) {
3691     case TextRenderingMode::AutoTextRendering:
3692         m_value.valueID = CSSValueAuto;
3693         break;
3694     case TextRenderingMode::OptimizeSpeed:
3695         m_value.valueID = CSSValueOptimizeSpeed;
3696         break;
3697     case TextRenderingMode::OptimizeLegibility:
3698         m_value.valueID = CSSValueOptimizeLegibility;
3699         break;
3700     case TextRenderingMode::GeometricPrecision:
3701         m_value.valueID = CSSValueGeometricPrecision;
3702         break;
3703     }
3704 }
3705
3706 template<> inline CSSPrimitiveValue::operator TextRenderingMode() const
3707 {
3708     ASSERT(isValueID());
3709
3710     switch (m_value.valueID) {
3711     case CSSValueAuto:
3712         return TextRenderingMode::AutoTextRendering;
3713     case CSSValueOptimizeSpeed:
3714         return TextRenderingMode::OptimizeSpeed;
3715     case CSSValueOptimizeLegibility:
3716         return TextRenderingMode::OptimizeLegibility;
3717     case CSSValueGeometricPrecision:
3718         return TextRenderingMode::GeometricPrecision;
3719     default:
3720         break;
3721     }
3722
3723     ASSERT_NOT_REACHED();
3724     return TextRenderingMode::AutoTextRendering;
3725 }
3726
3727 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Hyphens hyphens)
3728     : CSSValue(PrimitiveClass)
3729 {
3730     m_primitiveUnitType = CSS_VALUE_ID;
3731     switch (hyphens) {
3732     case Hyphens::None:
3733         m_value.valueID = CSSValueNone;
3734         break;
3735     case Hyphens::Manual:
3736         m_value.valueID = CSSValueManual;
3737         break;
3738     case Hyphens::Auto:
3739         m_value.valueID = CSSValueAuto;
3740         break;
3741     }
3742 }
3743
3744 template<> inline CSSPrimitiveValue::operator Hyphens() const
3745 {
3746     ASSERT(isValueID());
3747
3748     switch (m_value.valueID) {
3749     case CSSValueNone:
3750         return Hyphens::None;
3751     case CSSValueManual:
3752         return Hyphens::Manual;
3753     case CSSValueAuto:
3754         return Hyphens::Auto;
3755     default:
3756         break;
3757     }
3758
3759     ASSERT_NOT_REACHED();
3760     return Hyphens::Auto;
3761 }
3762
3763 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineSnap gridSnap)
3764     : CSSValue(PrimitiveClass)
3765 {
3766     m_primitiveUnitType = CSS_VALUE_ID;
3767     switch (gridSnap) {
3768     case LineSnap::None:
3769         m_value.valueID = CSSValueNone;
3770         break;
3771     case LineSnap::Baseline:
3772         m_value.valueID = CSSValueBaseline;
3773         break;
3774     case LineSnap::Contain:
3775         m_value.valueID = CSSValueContain;
3776         break;
3777     }
3778 }
3779
3780 template<> inline CSSPrimitiveValue::operator LineSnap() const
3781 {
3782     ASSERT(isValueID());
3783
3784     switch (m_value.valueID) {
3785     case CSSValueNone:
3786         return LineSnap::None;
3787     case CSSValueBaseline:
3788         return LineSnap::Baseline;
3789     case CSSValueContain:
3790         return LineSnap::Contain;
3791     default:
3792         break;
3793     }
3794
3795     ASSERT_NOT_REACHED();
3796     return LineSnap::None;
3797 }
3798
3799 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineAlign lineAlign)
3800     : CSSValue(PrimitiveClass)
3801 {
3802     m_primitiveUnitType = CSS_VALUE_ID;
3803     switch (lineAlign) {
3804     case LineAlign::None:
3805         m_value.valueID = CSSValueNone;
3806         break;
3807     case LineAlign::Edges:
3808         m_value.valueID = CSSValueEdges;
3809         break;
3810     }
3811 }
3812
3813 template<> inline CSSPrimitiveValue::operator LineAlign() const
3814 {
3815     ASSERT(isValueID());
3816
3817     switch (m_value.valueID) {
3818     case CSSValueNone:
3819         return LineAlign::None;
3820     case CSSValueEdges:
3821         return LineAlign::Edges;
3822     default:
3823         break;
3824     }
3825
3826     ASSERT_NOT_REACHED();
3827     return LineAlign::None;
3828 }
3829
3830 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(SpeakAs e)
3831     : CSSValue(PrimitiveClass)
3832 {
3833     m_primitiveUnitType = CSS_VALUE_ID;
3834     switch (e) {
3835     case SpeakAs::Normal:
3836         m_value.valueID = CSSValueNormal;
3837         break;
3838     case SpeakAs::SpellOut:
3839         m_value.valueID = CSSValueSpellOut;
3840         break;
3841     case SpeakAs::Digits:
3842         m_value.valueID = CSSValueDigits;
3843         break;
3844     case SpeakAs::LiteralPunctuation:
3845         m_value.valueID = CSSValueLiteralPunctuation;
3846         break;
3847     case SpeakAs::NoPunctuation:
3848         m_value.valueID = CSSValueNoPunctuation;
3849         break;
3850     }
3851 }
3852
3853 template<> inline CSSPrimitiveValue::operator Order() const
3854 {
3855     ASSERT(isValueID());
3856
3857     switch (m_value.valueID) {
3858     case CSSValueLogical:
3859         return Order::Logical;
3860     case CSSValueVisual:
3861         return Order::Visual;
3862     default:
3863         break;
3864     }
3865
3866     ASSERT_NOT_REACHED();
3867     return Order::Logical;
3868 }
3869
3870 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Order e)
3871     : CSSValue(PrimitiveClass)
3872 {
3873     m_primitiveUnitType = CSS_VALUE_ID;
3874     switch (e) {
3875     case Order::Logical:
3876         m_value.valueID = CSSValueLogical;
3877         break;
3878     case Order::Visual:
3879         m_value.valueID = CSSValueVisual;
3880         break;
3881     }
3882 }
3883
3884 template<> inline CSSPrimitiveValue::operator OptionSet<SpeakAs>() const
3885 {
3886     ASSERT(isValueID());
3887
3888     switch (m_value.valueID) {
3889     case CSSValueNormal:
3890         return OptionSet<SpeakAs> { };
3891     case CSSValueSpellOut:
3892         return SpeakAs::SpellOut;
3893     case CSSValueDigits:
3894         return SpeakAs::Digits;
3895     case CSSValueLiteralPunctuation:
3896         return SpeakAs::LiteralPunctuation;
3897     case CSSValueNoPunctuation:
3898         return SpeakAs::NoPunctuation;
3899     default:
3900         break;
3901     }
3902
3903     ASSERT_NOT_REACHED();
3904     return OptionSet<SpeakAs> { };
3905 }
3906
3907 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(BlendMode blendMode)
3908     : CSSValue(PrimitiveClass)
3909 {
3910     m_primitiveUnitType = CSS_VALUE_ID;
3911     switch (blendMode) {
3912     case BlendMode::Normal:
3913         m_value.valueID = CSSValueNormal;
3914         break;
3915     case BlendMode::Multiply:
3916         m_value.valueID = CSSValueMultiply;
3917         break;
3918     case BlendMode::Screen:
3919         m_value.valueID = CSSValueScreen;
3920         break;
3921     case BlendMode::Overlay:
3922         m_value.valueID = CSSValueOverlay;
3923         break;
3924     case BlendMode::Darken:
3925         m_value.valueID = CSSValueDarken;
3926         break;
3927     case BlendMode::Lighten:
3928         m_value.valueID = CSSValueLighten;
3929         break;
3930     case BlendMode::ColorDodge:
3931         m_value.valueID = CSSValueColorDodge;
3932         break;
3933     case BlendMode::ColorBurn:
3934         m_value.valueID = CSSValueColorBurn;
3935         break;
3936     case BlendMode::HardLight:
3937         m_value.valueID = CSSValueHardLight;
3938         break;
3939     case BlendMode::SoftLight:
3940         m_value.valueID = CSSValueSoftLight;
3941         break;
3942     case BlendMode::Difference:
3943         m_value.valueID = CSSValueDifference;
3944         break;
3945     case BlendMode::Exclusion:
3946         m_value.valueID = CSSValueExclusion;
3947         break;
3948     case BlendMode::Hue:
3949         m_value.valueID = CSSValueHue;
3950         break;
3951     case BlendMode::Saturation:
3952         m_value.valueID = CSSValueSaturation;
3953         break;
3954     case BlendMode::Color:
3955         m_value.valueID = CSSValueColor;
3956         break;
3957     case BlendMode::Luminosity:
3958         m_value.valueID = CSSValueLuminosity;
3959         break;
3960     case BlendMode::PlusDarker:
3961         m_value.valueID = CSSValuePlusDarker;
3962         break;
3963     case BlendMode::PlusLighter:
3964         m_value.valueID = CSSValuePlusLighter;
3965         break;
3966     }
3967 }
3968
3969 template<> inline CSSPrimitiveValue::operator BlendMode() const
3970 {
3971     ASSERT(isValueID());
3972
3973     switch (m_value.valueID) {
3974     case CSSValueNormal:
3975         return BlendMode::Normal;
3976     case CSSValueMultiply:
3977         return BlendMode::Multiply;
3978     case CSSValueScreen:
3979         return BlendMode::Screen;
3980     case CSSValueOverlay:
3981         return BlendMode::Overlay;
3982     case CSSValueDarken:
3983         return BlendMode::Darken;
3984     case CSSValueLighten:
3985         return BlendMode::Lighten;
3986     case CSSValueColorDodge:
3987         return BlendMode::ColorDodge;
3988     case CSSValueColorBurn:
3989         return BlendMode::ColorBurn;
3990     case CSSValueHardLight:
3991         return BlendMode::HardLight;
3992     case CSSValueSoftLight:
3993         return BlendMode::SoftLight;
3994     case CSSValueDifference:
3995         return BlendMode::Difference;
3996     case CSSValueExclusion:
3997         return BlendMode::Exclusion;
3998     case CSSValueHue:
3999         return BlendMode::Hue;
4000     case CSSValueSaturation:
4001         return BlendMode::Saturation;
4002     case CSSValueColor:
4003         return BlendMode::Color;
4004     case CSSValueLuminosity:
4005         return BlendMode::Luminosity;
4006     case CSSValuePlusDarker:
4007         return BlendMode::PlusDarker;
4008     case CSSValuePlusLighter:
4009         return BlendMode::PlusLighter;
4010     default:
4011         break;
4012     }
4013
4014     ASSERT_NOT_REACHED();
4015     return BlendMode::Normal;
4016 }
4017
4018 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(Isolation isolation)
4019     : CSSValue(PrimitiveClass)
4020 {
4021     m_primitiveUnitType = CSS_VALUE_ID;
4022     switch (isolation) {
4023     case Isolation::Auto:
4024         m_value.valueID = CSSValueAuto;
4025         break;
4026     case Isolation::Isolate:
4027         m_value.valueID = CSSValueIsolate;
4028         break;
4029     default:
4030         ASSERT_NOT_REACHED();
4031     }
4032 }
4033
4034 template<> inline CSSPrimitiveValue::operator Isolation() const
4035 {
4036     ASSERT(isValueID());
4037     switch (m_value.valueID) {
4038     case CSSValueAuto:
4039         return Isolation::Auto;
4040     case CSSValueIsolate:
4041         return Isolation::Isolate;
4042     default:
4043         break;
4044     }
4045
4046     ASSERT_NOT_REACHED();
4047     return Isolation::Auto;
4048 }
4049
4050 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineCap e)
4051     : CSSValue(PrimitiveClass)
4052 {
4053     m_primitiveUnitType = CSS_VALUE_ID;
4054     switch (e) {
4055     case ButtCap:
4056         m_value.valueID = CSSValueButt;
4057         break;
4058     case RoundCap:
4059         m_value.valueID = CSSValueRound;
4060         break;
4061     case SquareCap:
4062         m_value.valueID = CSSValueSquare;
4063         break;
4064     }
4065 }
4066
4067 template<> inline CSSPrimitiveValue::operator LineCap() const
4068 {
4069     ASSERT(isValueID());
4070
4071     switch (m_value.valueID) {
4072     case CSSValueButt:
4073         return ButtCap;
4074     case CSSValueRound:
4075         return RoundCap;
4076     case CSSValueSquare:
4077         return SquareCap;
4078     default:
4079         break;
4080     }
4081
4082     ASSERT_NOT_REACHED();
4083     return ButtCap;
4084 }
4085
4086 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineJoin e)
4087     : CSSValue(PrimitiveClass)
4088 {
4089     m_primitiveUnitType = CSS_VALUE_ID;
4090     switch (e) {
4091     case MiterJoin:
4092         m_value.valueID = CSSValueMiter;
4093         break;
4094     case RoundJoin:
4095         m_value.valueID = CSSValueRound;
4096         break;
4097     case BevelJoin:
4098         m_value.valueID = CSSValueBevel;
4099         break;
4100     }
4101 }
4102
4103 template<> inline CSSPrimitiveValue::operator LineJoin() const
4104 {
4105     ASSERT(isValueID());
4106
4107     switch (m_value.valueID) {
4108     case CSSValueMiter:
4109         return MiterJoin;
4110     case CSSValueRound:
4111         return RoundJoin;
4112     case CSSValueBevel:
4113         return BevelJoin;
4114     default:
4115         break;
4116     }
4117
4118     ASSERT_NOT_REACHED();
4119     return MiterJoin;
4120 }
4121
4122 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WindRule e)
4123     : CSSValue(PrimitiveClass)
4124 {
4125     m_primitiveUnitType = CSS_VALUE_ID;
4126     switch (e) {
4127     case WindRule::NonZero:
4128         m_value.valueID = CSSValueNonzero;
4129         break;
4130     case WindRule::EvenOdd:
4131         m_value.valueID = CSSValueEvenodd;
4132         break;
4133     }
4134 }
4135
4136 template<> inline CSSPrimitiveValue::operator WindRule() const
4137 {
4138     ASSERT(isValueID());
4139
4140     switch (m_value.valueID) {
4141     case CSSValueNonzero:
4142         return WindRule::NonZero;
4143     case CSSValueEvenodd:
4144         return WindRule::EvenOdd;
4145     default:
4146         break;
4147     }
4148
4149     ASSERT_NOT_REACHED();
4150     return WindRule::NonZero;
4151 }
4152
4153
4154 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(AlignmentBaseline e)
4155     : CSSValue(PrimitiveClass)
4156 {
4157     m_primitiveUnitType = CSS_VALUE_ID;
4158     switch (e) {
4159     case AlignmentBaseline::Auto:
4160         m_value.valueID = CSSValueAuto;
4161         break;
4162     case AlignmentBaseline::Baseline:
4163         m_value.valueID = CSSValueBaseline;
4164         break;
4165     case AlignmentBaseline::BeforeEdge:
4166         m_value.valueID = CSSValueBeforeEdge;
4167         break;
4168     case AlignmentBaseline::TextBeforeEdge:
4169         m_value.valueID = CSSValueTextBeforeEdge;
4170         break;
4171     case AlignmentBaseline::Middle:
4172         m_value.valueID = CSSValueMiddle;
4173         break;
4174     case AlignmentBaseline::Central:
4175         m_value.valueID = CSSValueCentral;
4176         break;
4177     case AlignmentBaseline::AfterEdge:
4178         m_value.valueID = CSSValueAfterEdge;
4179         break;
4180     case AlignmentBaseline::TextAfterEdge:
4181         m_value.valueID = CSSValueTextAfterEdge;
4182         break;
4183     case AlignmentBaseline::Ideographic:
4184         m_value.valueID = CSSValueIdeographic;
4185         break;
4186     case AlignmentBaseline::Alphabetic:
4187         m_value.valueID = CSSValueAlphabetic;
4188         break;
4189     case AlignmentBaseline::Hanging:
4190         m_value.valueID = CSSValueHanging;
4191         break;
4192     case AlignmentBaseline::Mathematical:
4193         m_value.valueID = CSSValueMathematical;
4194         break;
4195     }
4196 }
4197
4198 template<> inline CSSPrimitiveValue::operator AlignmentBaseline() const
4199 {
4200     ASSERT(isValueID());
4201
4202     switch (m_value.valueID) {
4203     case CSSValueAuto:
4204         return AlignmentBaseline::Auto;