2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
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.
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.
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.
22 #include "core/css/CSSProperty.h"
24 #include "core/StylePropertyShorthand.h"
25 #include "core/css/CSSValueList.h"
26 #include "core/rendering/style/RenderStyleConstants.h"
30 struct SameSizeAsCSSProperty {
35 COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small);
37 CSSPropertyID StylePropertyMetadata::shorthandID() const
39 if (!m_isSetFromShorthand)
40 return CSSPropertyInvalid;
42 Vector<StylePropertyShorthand, 4> shorthands;
43 getMatchingShorthandsForLonghand(static_cast<CSSPropertyID>(m_propertyID), &shorthands);
44 ASSERT(shorthands.size() && m_indexInShorthandsVector >= 0 && m_indexInShorthandsVector < shorthands.size());
45 return shorthands.at(m_indexInShorthandsVector).id();
48 void CSSProperty::wrapValueInCommaSeparatedList()
50 RefPtrWillBeRawPtr<CSSValue> value = m_value.release();
51 m_value = CSSValueList::createCommaSeparated();
52 toCSSValueList(m_value.get())->append(value.release());
55 enum LogicalBoxSide { BeforeSide, EndSide, AfterSide, StartSide };
56 enum PhysicalBoxSide { TopSide, RightSide, BottomSide, LeftSide };
58 static CSSPropertyID resolveToPhysicalProperty(TextDirection direction, WritingMode writingMode, LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand)
60 if (direction == LTR) {
61 if (writingMode == TopToBottomWritingMode) {
62 // The common case. The logical and physical box sides match.
63 // Left = Start, Right = End, Before = Top, After = Bottom
64 return shorthand.properties()[logicalSide];
67 if (writingMode == BottomToTopWritingMode) {
68 // Start = Left, End = Right, Before = Bottom, After = Top.
69 switch (logicalSide) {
71 return shorthand.properties()[LeftSide];
73 return shorthand.properties()[RightSide];
75 return shorthand.properties()[BottomSide];
77 return shorthand.properties()[TopSide];
81 if (writingMode == LeftToRightWritingMode) {
82 // Start = Top, End = Bottom, Before = Left, After = Right.
83 switch (logicalSide) {
85 return shorthand.properties()[TopSide];
87 return shorthand.properties()[BottomSide];
89 return shorthand.properties()[LeftSide];
91 return shorthand.properties()[RightSide];
95 // Start = Top, End = Bottom, Before = Right, After = Left
96 switch (logicalSide) {
98 return shorthand.properties()[TopSide];
100 return shorthand.properties()[BottomSide];
102 return shorthand.properties()[RightSide];
104 return shorthand.properties()[LeftSide];
108 if (writingMode == TopToBottomWritingMode) {
109 // Start = Right, End = Left, Before = Top, After = Bottom
110 switch (logicalSide) {
112 return shorthand.properties()[RightSide];
114 return shorthand.properties()[LeftSide];
116 return shorthand.properties()[TopSide];
118 return shorthand.properties()[BottomSide];
122 if (writingMode == BottomToTopWritingMode) {
123 // Start = Right, End = Left, Before = Bottom, After = Top
124 switch (logicalSide) {
126 return shorthand.properties()[RightSide];
128 return shorthand.properties()[LeftSide];
130 return shorthand.properties()[BottomSide];
132 return shorthand.properties()[TopSide];
136 if (writingMode == LeftToRightWritingMode) {
137 // Start = Bottom, End = Top, Before = Left, After = Right
138 switch (logicalSide) {
140 return shorthand.properties()[BottomSide];
142 return shorthand.properties()[TopSide];
144 return shorthand.properties()[LeftSide];
146 return shorthand.properties()[RightSide];
150 // Start = Bottom, End = Top, Before = Right, After = Left
151 switch (logicalSide) {
153 return shorthand.properties()[BottomSide];
155 return shorthand.properties()[TopSide];
157 return shorthand.properties()[RightSide];
159 return shorthand.properties()[LeftSide];
163 enum LogicalExtent { LogicalWidth, LogicalHeight };
165 static CSSPropertyID resolveToPhysicalProperty(WritingMode writingMode, LogicalExtent logicalSide, const CSSPropertyID* properties)
167 if (writingMode == TopToBottomWritingMode || writingMode == BottomToTopWritingMode)
168 return properties[logicalSide];
169 return logicalSide == LogicalWidth ? properties[1] : properties[0];
172 static const StylePropertyShorthand& borderDirections()
174 static const CSSPropertyID properties[4] = { CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft };
175 DEFINE_STATIC_LOCAL(StylePropertyShorthand, borderDirections, (CSSPropertyBorder, properties, WTF_ARRAY_LENGTH(properties)));
176 return borderDirections;
179 CSSPropertyID CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID, TextDirection direction, WritingMode writingMode)
181 switch (propertyID) {
182 case CSSPropertyWebkitMarginEnd:
183 return resolveToPhysicalProperty(direction, writingMode, EndSide, marginShorthand());
184 case CSSPropertyWebkitMarginStart:
185 return resolveToPhysicalProperty(direction, writingMode, StartSide, marginShorthand());
186 case CSSPropertyWebkitMarginBefore:
187 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, marginShorthand());
188 case CSSPropertyWebkitMarginAfter:
189 return resolveToPhysicalProperty(direction, writingMode, AfterSide, marginShorthand());
190 case CSSPropertyWebkitPaddingEnd:
191 return resolveToPhysicalProperty(direction, writingMode, EndSide, paddingShorthand());
192 case CSSPropertyWebkitPaddingStart:
193 return resolveToPhysicalProperty(direction, writingMode, StartSide, paddingShorthand());
194 case CSSPropertyWebkitPaddingBefore:
195 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, paddingShorthand());
196 case CSSPropertyWebkitPaddingAfter:
197 return resolveToPhysicalProperty(direction, writingMode, AfterSide, paddingShorthand());
198 case CSSPropertyWebkitBorderEnd:
199 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderDirections());
200 case CSSPropertyWebkitBorderStart:
201 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderDirections());
202 case CSSPropertyWebkitBorderBefore:
203 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderDirections());
204 case CSSPropertyWebkitBorderAfter:
205 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderDirections());
206 case CSSPropertyWebkitBorderEndColor:
207 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderColorShorthand());
208 case CSSPropertyWebkitBorderStartColor:
209 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderColorShorthand());
210 case CSSPropertyWebkitBorderBeforeColor:
211 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderColorShorthand());
212 case CSSPropertyWebkitBorderAfterColor:
213 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderColorShorthand());
214 case CSSPropertyWebkitBorderEndStyle:
215 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderStyleShorthand());
216 case CSSPropertyWebkitBorderStartStyle:
217 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderStyleShorthand());
218 case CSSPropertyWebkitBorderBeforeStyle:
219 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderStyleShorthand());
220 case CSSPropertyWebkitBorderAfterStyle:
221 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderStyleShorthand());
222 case CSSPropertyWebkitBorderEndWidth:
223 return resolveToPhysicalProperty(direction, writingMode, EndSide, borderWidthShorthand());
224 case CSSPropertyWebkitBorderStartWidth:
225 return resolveToPhysicalProperty(direction, writingMode, StartSide, borderWidthShorthand());
226 case CSSPropertyWebkitBorderBeforeWidth:
227 return resolveToPhysicalProperty(direction, writingMode, BeforeSide, borderWidthShorthand());
228 case CSSPropertyWebkitBorderAfterWidth:
229 return resolveToPhysicalProperty(direction, writingMode, AfterSide, borderWidthShorthand());
230 case CSSPropertyWebkitLogicalWidth: {
231 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
232 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
234 case CSSPropertyWebkitLogicalHeight: {
235 const CSSPropertyID properties[2] = { CSSPropertyWidth, CSSPropertyHeight };
236 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
238 case CSSPropertyWebkitMinLogicalWidth: {
239 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
240 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
242 case CSSPropertyWebkitMinLogicalHeight: {
243 const CSSPropertyID properties[2] = { CSSPropertyMinWidth, CSSPropertyMinHeight };
244 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
246 case CSSPropertyWebkitMaxLogicalWidth: {
247 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
248 return resolveToPhysicalProperty(writingMode, LogicalWidth, properties);
250 case CSSPropertyWebkitMaxLogicalHeight: {
251 const CSSPropertyID properties[2] = { CSSPropertyMaxWidth, CSSPropertyMaxHeight };
252 return resolveToPhysicalProperty(writingMode, LogicalHeight, properties);
259 bool CSSProperty::isAffectedByAllProperty(CSSPropertyID propertyID)
261 if (propertyID == CSSPropertyAll)
264 // all shorthand spec says:
265 // The all property is a shorthand that resets all CSS properties except
266 // direction and unicode-bidi. It only accepts the CSS-wide keywords.
267 // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
268 // So CSSPropertyUnicodeBidi and CSSPropertyDirection are not
269 // affected by all property.
270 return propertyID != CSSPropertyUnicodeBidi && propertyID != CSSPropertyDirection;