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