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
29namespace WebCore {
30
31struct SameSizeAsCSSProperty {
32 uint32_t bitfields;
33 void* value;
34};
35
36COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small);
37
38CSSPropertyID 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
48void CSSProperty::wrapValueInCommaSeparatedList()
49{
50 auto list = CSSValueList::createCommaSeparated();
51 list.get().append(m_value.releaseNonNull());
52 m_value = WTFMove(list);
53}
54
55static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand)
56{
57 return shorthand.properties()[static_cast<size_t>(mapLogicalSideToPhysicalSide(makeTextFlow(writingMode, direction), logicalSide))];
58}
59
60enum LogicalExtent { LogicalWidth, LogicalHeight };
61
62static 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
69static 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
76CSSPropertyID CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID, TextDirection direction, WritingMode writingMode)
77{
78 switch (propertyID) {
79 case CSSPropertyInsetInlineEnd:
80 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, insetShorthand());
81 case CSSPropertyInsetInlineStart:
82 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, insetShorthand());
83 case CSSPropertyInsetBlockStart:
84 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, insetShorthand());
85 case CSSPropertyInsetBlockEnd:
86 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, insetShorthand());
87 case CSSPropertyMarginInlineEnd:
88 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, marginShorthand());
89 case CSSPropertyMarginInlineStart:
90 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, marginShorthand());
91 case CSSPropertyMarginBlockStart:
92 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, marginShorthand());
93 case CSSPropertyMarginBlockEnd:
94 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, marginShorthand());
95 case CSSPropertyPaddingInlineEnd:
96 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, paddingShorthand());
97 case CSSPropertyPaddingInlineStart:
98 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, paddingShorthand());
99 case CSSPropertyPaddingBlockStart:
100 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, paddingShorthand());
101 case CSSPropertyPaddingBlockEnd:
102 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, paddingShorthand());
103 case CSSPropertyBorderInlineEnd:
104 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, borderDirections());
105 case CSSPropertyBorderInlineStart:
106 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, borderDirections());
107 case CSSPropertyBorderBlockStart:
108 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, borderDirections());
109 case CSSPropertyBorderBlockEnd:
110 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, borderDirections());
111 case CSSPropertyBorderInlineEndColor:
112 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, borderColorShorthand());
113 case CSSPropertyBorderInlineStartColor:
114 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, borderColorShorthand());
115 case CSSPropertyBorderBlockStartColor:
116 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, borderColorShorthand());
117 case CSSPropertyBorderBlockEndColor:
118 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, borderColorShorthand());
119 case CSSPropertyBorderInlineEndStyle:
120 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, borderStyleShorthand());
121 case CSSPropertyBorderInlineStartStyle:
122 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, borderStyleShorthand());
123 case CSSPropertyBorderBlockStartStyle:
124 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, borderStyleShorthand());
125 case CSSPropertyBorderBlockEndStyle:
126 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, borderStyleShorthand());
127 case CSSPropertyBorderInlineEndWidth:
128 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::End, borderWidthShorthand());
129 case CSSPropertyBorderInlineStartWidth:
130 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Start, borderWidthShorthand());
131 case CSSPropertyBorderBlockStartWidth:
132 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::Before, borderWidthShorthand());
133 case CSSPropertyBorderBlockEndWidth:
134 return resolveToPhysicalProperty(direction, writingMode, LogicalBoxSide::After, borderWidthShorthand());
135 case CSSPropertyInlineSize: {
136 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
137 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
138 }
139 case CSSPropertyBlockSize: {
140 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
141 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
142 }
143 case CSSPropertyMinInlineSize: {
144 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
145 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
146 }
147 case CSSPropertyMinBlockSize: {
148 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
149 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
150 }
151 case CSSPropertyMaxInlineSize: {
152 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
153 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
154 }
155 case CSSPropertyMaxBlockSize: {
156 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
157 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
158 }
159 default:
160 return propertyID;
161 }
162}
163
164bool CSSProperty::isDescriptorOnly(CSSPropertyID propertyID)
165{
166 switch (propertyID) {
167#if ENABLE(CSS_DEVICE_ADAPTATION)
168 case CSSPropertyMinZoom:
169 case CSSPropertyMaxZoom:
170 case CSSPropertyOrientation:
171 case CSSPropertyUserZoom:
172#endif
173 case CSSPropertySrc:
174 case CSSPropertyUnicodeRange:
175 case CSSPropertyFontDisplay:
176 return true;
177 default:
178 return false;
179 }
180}
181
182bool CSSProperty::isDirectionAwareProperty(CSSPropertyID propertyID)
183{
184 switch (propertyID) {
185 case CSSPropertyBorderInlineEndColor:
186 case CSSPropertyBorderInlineEndStyle:
187 case CSSPropertyBorderInlineEndWidth:
188 case CSSPropertyBorderInlineStartColor:
189 case CSSPropertyBorderInlineStartStyle:
190 case CSSPropertyBorderInlineStartWidth:
191 case CSSPropertyBorderBlockStartColor:
192 case CSSPropertyBorderBlockStartStyle:
193 case CSSPropertyBorderBlockStartWidth:
194 case CSSPropertyBorderBlockEndColor:
195 case CSSPropertyBorderBlockEndStyle:
196 case CSSPropertyBorderBlockEndWidth:
197 case CSSPropertyInsetInlineEnd:
198 case CSSPropertyInsetInlineStart:
199 case CSSPropertyInsetBlockStart:
200 case CSSPropertyInsetBlockEnd:
201 case CSSPropertyMarginInlineEnd:
202 case CSSPropertyMarginInlineStart:
203 case CSSPropertyMarginBlockStart:
204 case CSSPropertyMarginBlockEnd:
205 case CSSPropertyPaddingInlineEnd:
206 case CSSPropertyPaddingInlineStart:
207 case CSSPropertyPaddingBlockStart:
208 case CSSPropertyPaddingBlockEnd:
209 case CSSPropertyInlineSize:
210 case CSSPropertyBlockSize:
211 case CSSPropertyMinInlineSize:
212 case CSSPropertyMinBlockSize:
213 case CSSPropertyMaxInlineSize:
214 case CSSPropertyMaxBlockSize:
215 return true;
216 default:
217 return false;
218 }
219}
220
221} // namespace WebCore
222