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