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