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