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