Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebCore / css / CSSProperty.cpp
1 /**
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006 Apple Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "CSSProperty.h"
23
24 #include "CSSValueList.h"
25 #include "StylePropertyShorthand.h"
26 #include "StylePropertyShorthandFunctions.h"
27 #include <wtf/NeverDestroyed.h>
28
29 namespace WebCore {
30
31 struct SameSizeAsCSSProperty {
32     uint32_t bitfields;
33     void* value;
34 };
35
36 COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small);
37
38 CSSPropertyID StylePropertyMetadata::shorthandID() const
39 {
40     if (!m_isSetFromShorthand)
41         return CSSPropertyInvalid;
42
43     auto shorthands = matchingShorthandsForLonghand(static_cast<CSSPropertyID>(m_propertyID));
44     ASSERT(shorthands.size() && m_indexInShorthandsVector >= 0 && m_indexInShorthandsVector < shorthands.size());
45     return shorthands[m_indexInShorthandsVector].id();
46 }
47
48 void CSSProperty::wrapValueInCommaSeparatedList()
49 {
50     auto list = CSSValueList::createCommaSeparated();
51     list.get().append(m_value.releaseNonNull());
52     m_value = WTFMove(list);
53 }
54
55 static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand)
56 {
57     return shorthand.properties()[mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), logicalSide)];
58 }
59
60 enum LogicalExtent { LogicalWidth, LogicalHeight };
61
62 static CSSPropertyID resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const CSSPropertyID* properties)
63 {
64     if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode)
65         return properties[logicalSide];
66     return logicalSide == LogicalWidth ? properties[1] : properties[0];
67 }
68
69 static const StylePropertyShorthand& borderDirections()
70 {
71     static const CSSPropertyID properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
72     static const StylePropertyShorthand borderDirections(CSSPropertyBorder, properties);
73     return borderDirections;
74 }
75
76 CSSPropertyID CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID, TextDirection direction, WritingMode writingMode)
77 {
78     switch (propertyID) {
79     case CSSPropertyWebkitMarginEnd:
80         return resolveToPhysicalProperty(direction, writingMode, EndSide, marginShorthand());
81     case CSSPropertyWebkitMarginStart:
82         return resolveToPhysicalProperty(direction, writingMode, StartSide, marginShorthand());
83     case CSSPropertyWebkitMarginBefore:
84         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, marginShorthand());
85     case CSSPropertyWebkitMarginAfter:
86         return resolveToPhysicalProperty(direction, writingMode, AfterSide, marginShorthand());
87     case CSSPropertyWebkitPaddingEnd:
88         return resolveToPhysicalProperty(direction, writingMode, EndSide, paddingShorthand());
89     case CSSPropertyWebkitPaddingStart:
90         return resolveToPhysicalProperty(direction, writingMode, StartSide, paddingShorthand());
91     case CSSPropertyWebkitPaddingBefore:
92         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, paddingShorthand());
93     case CSSPropertyWebkitPaddingAfter:
94         return resolveToPhysicalProperty(direction, writingMode, AfterSide, paddingShorthand());
95     case CSSPropertyWebkitBorderEnd:
96         return resolveToPhysicalProperty(direction, writingMode, EndSide, borderDirections());
97     case CSSPropertyWebkitBorderStart:
98         return resolveToPhysicalProperty(direction, writingMode, StartSide, borderDirections());
99     case CSSPropertyWebkitBorderBefore:
100         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderDirections());
101     case CSSPropertyWebkitBorderAfter:
102         return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderDirections());
103     case CSSPropertyWebkitBorderEndColor:
104         return resolveToPhysicalProperty(direction, writingMode, EndSide, borderColorShorthand());
105     case CSSPropertyWebkitBorderStartColor:
106         return resolveToPhysicalProperty(direction, writingMode, StartSide, borderColorShorthand());
107     case CSSPropertyWebkitBorderBeforeColor:
108         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderColorShorthand());
109     case CSSPropertyWebkitBorderAfterColor:
110         return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderColorShorthand());
111     case CSSPropertyWebkitBorderEndStyle:
112         return resolveToPhysicalProperty(direction, writingMode, EndSide, borderStyleShorthand());
113     case CSSPropertyWebkitBorderStartStyle:
114         return resolveToPhysicalProperty(direction, writingMode, StartSide, borderStyleShorthand());
115     case CSSPropertyWebkitBorderBeforeStyle:
116         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderStyleShorthand());
117     case CSSPropertyWebkitBorderAfterStyle:
118         return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderStyleShorthand());
119     case CSSPropertyWebkitBorderEndWidth:
120         return resolveToPhysicalProperty(direction, writingMode, EndSide, borderWidthShorthand());
121     case CSSPropertyWebkitBorderStartWidth:
122         return resolveToPhysicalProperty(direction, writingMode, StartSide, borderWidthShorthand());
123     case CSSPropertyWebkitBorderBeforeWidth:
124         return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderWidthShorthand());
125     case CSSPropertyWebkitBorderAfterWidth:
126         return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderWidthShorthand());
127     case CSSPropertyWebkitLogicalWidth: {
128         const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
129         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
130     }
131     case CSSPropertyWebkitLogicalHeight: {
132         const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
133         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
134     }
135     case CSSPropertyWebkitMinLogicalWidth: {
136         const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
137         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
138     }
139     case CSSPropertyWebkitMinLogicalHeight: {
140         const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
141         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
142     }
143     case CSSPropertyWebkitMaxLogicalWidth: {
144         const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
145         return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
146     }
147     case CSSPropertyWebkitMaxLogicalHeight: {
148         const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
149         return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
150     }
151     default:
152         return propertyID;
153     }
154 }
155
156 bool CSSProperty::isDescriptorOnly(CSSPropertyID propertyID)
157 {
158     switch (propertyID) {
159 #if ENABLE(CSS_DEVICE_ADAPTATION)
160     case CSSPropertyMinZoom:
161     case CSSPropertyMaxZoom:
162     case CSSPropertyOrientation:
163     case CSSPropertyUserZoom:
164 #endif
165     case CSSPropertySrc:
166     case CSSPropertyUnicodeRange:
167         return true;
168     default:
169         return false;
170     }
171 }
172
173 bool CSSProperty::isDirectionAwareProperty(CSSPropertyID propertyID)
174 {
175     switch (propertyID) {
176     case CSSPropertyWebkitBorderEndColor:
177     case CSSPropertyWebkitBorderEndStyle:
178     case CSSPropertyWebkitBorderEndWidth:
179     case CSSPropertyWebkitBorderStartColor:
180     case CSSPropertyWebkitBorderStartStyle:
181     case CSSPropertyWebkitBorderStartWidth:
182     case CSSPropertyWebkitBorderBeforeColor:
183     case CSSPropertyWebkitBorderBeforeStyle:
184     case CSSPropertyWebkitBorderBeforeWidth:
185     case CSSPropertyWebkitBorderAfterColor:
186     case CSSPropertyWebkitBorderAfterStyle:
187     case CSSPropertyWebkitBorderAfterWidth:
188     case CSSPropertyWebkitMarginEnd:
189     case CSSPropertyWebkitMarginStart:
190     case CSSPropertyWebkitMarginBefore:
191     case CSSPropertyWebkitMarginAfter:
192     case CSSPropertyWebkitPaddingEnd:
193     case CSSPropertyWebkitPaddingStart:
194     case CSSPropertyWebkitPaddingBefore:
195     case CSSPropertyWebkitPaddingAfter:
196     case CSSPropertyWebkitLogicalWidth:
197     case CSSPropertyWebkitLogicalHeight:
198     case CSSPropertyWebkitMinLogicalWidth:
199     case CSSPropertyWebkitMinLogicalHeight:
200     case CSSPropertyWebkitMaxLogicalWidth:
201     case CSSPropertyWebkitMaxLogicalHeight:
202         return true;
203     default:
204         return false;
205     }
206 }
207
208 } // namespace WebCore