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/style/ComputedStyleConstants.h"
29 struct SameSizeAsCSSProperty
{
34 static_assert(sizeof(CSSProperty
) == sizeof(SameSizeAsCSSProperty
), "CSSProperty should stay small");
36 CSSPropertyID
StylePropertyMetadata::shorthandID() const
38 if (!m_isSetFromShorthand
)
39 return CSSPropertyInvalid
;
41 Vector
<StylePropertyShorthand
, 4> shorthands
;
42 getMatchingShorthandsForLonghand(static_cast<CSSPropertyID
>(m_propertyID
), &shorthands
);
43 ASSERT(shorthands
.size() && m_indexInShorthandsVector
>= 0 && m_indexInShorthandsVector
< shorthands
.size());
44 return shorthands
.at(m_indexInShorthandsVector
).id();
47 enum LogicalBoxSide
{ BeforeSide
, EndSide
, AfterSide
, StartSide
};
48 enum PhysicalBoxSide
{ TopSide
, RightSide
, BottomSide
, LeftSide
};
50 static CSSPropertyID
resolveToPhysicalProperty(TextDirection direction
, WritingMode writingMode
, LogicalBoxSide logicalSide
, const StylePropertyShorthand
& shorthand
)
52 if (direction
== LTR
) {
53 if (writingMode
== TopToBottomWritingMode
) {
54 // The common case. The logical and physical box sides match.
55 // Left = Start, Right = End, Before = Top, After = Bottom
56 return shorthand
.properties()[logicalSide
];
59 if (writingMode
== BottomToTopWritingMode
) {
60 // Start = Left, End = Right, Before = Bottom, After = Top.
61 switch (logicalSide
) {
63 return shorthand
.properties()[LeftSide
];
65 return shorthand
.properties()[RightSide
];
67 return shorthand
.properties()[BottomSide
];
69 return shorthand
.properties()[TopSide
];
73 if (writingMode
== LeftToRightWritingMode
) {
74 // Start = Top, End = Bottom, Before = Left, After = Right.
75 switch (logicalSide
) {
77 return shorthand
.properties()[TopSide
];
79 return shorthand
.properties()[BottomSide
];
81 return shorthand
.properties()[LeftSide
];
83 return shorthand
.properties()[RightSide
];
87 // Start = Top, End = Bottom, Before = Right, After = Left
88 switch (logicalSide
) {
90 return shorthand
.properties()[TopSide
];
92 return shorthand
.properties()[BottomSide
];
94 return shorthand
.properties()[RightSide
];
96 return shorthand
.properties()[LeftSide
];
100 if (writingMode
== TopToBottomWritingMode
) {
101 // Start = Right, End = Left, Before = Top, After = Bottom
102 switch (logicalSide
) {
104 return shorthand
.properties()[RightSide
];
106 return shorthand
.properties()[LeftSide
];
108 return shorthand
.properties()[TopSide
];
110 return shorthand
.properties()[BottomSide
];
114 if (writingMode
== BottomToTopWritingMode
) {
115 // Start = Right, End = Left, Before = Bottom, After = Top
116 switch (logicalSide
) {
118 return shorthand
.properties()[RightSide
];
120 return shorthand
.properties()[LeftSide
];
122 return shorthand
.properties()[BottomSide
];
124 return shorthand
.properties()[TopSide
];
128 if (writingMode
== LeftToRightWritingMode
) {
129 // Start = Bottom, End = Top, Before = Left, After = Right
130 switch (logicalSide
) {
132 return shorthand
.properties()[BottomSide
];
134 return shorthand
.properties()[TopSide
];
136 return shorthand
.properties()[LeftSide
];
138 return shorthand
.properties()[RightSide
];
142 // Start = Bottom, End = Top, Before = Right, After = Left
143 switch (logicalSide
) {
145 return shorthand
.properties()[BottomSide
];
147 return shorthand
.properties()[TopSide
];
149 return shorthand
.properties()[RightSide
];
151 return shorthand
.properties()[LeftSide
];
155 enum LogicalExtent
{ LogicalWidth
, LogicalHeight
};
157 static CSSPropertyID
resolveToPhysicalProperty(WritingMode writingMode
, LogicalExtent logicalSide
, const CSSPropertyID
* properties
)
159 if (writingMode
== TopToBottomWritingMode
|| writingMode
== BottomToTopWritingMode
)
160 return properties
[logicalSide
];
161 return logicalSide
== LogicalWidth
? properties
[1] : properties
[0];
164 static const StylePropertyShorthand
& borderDirections()
166 static const CSSPropertyID properties
[4] = { CSSPropertyBorderTop
, CSSPropertyBorderRight
, CSSPropertyBorderBottom
, CSSPropertyBorderLeft
};
167 DEFINE_STATIC_LOCAL(StylePropertyShorthand
, borderDirections
, (CSSPropertyBorder
, properties
, WTF_ARRAY_LENGTH(properties
)));
168 return borderDirections
;
171 CSSPropertyID
CSSProperty::resolveDirectionAwareProperty(CSSPropertyID propertyID
, TextDirection direction
, WritingMode writingMode
)
173 switch (propertyID
) {
174 case CSSPropertyWebkitMarginEnd
:
175 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, marginShorthand());
176 case CSSPropertyWebkitMarginStart
:
177 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, marginShorthand());
178 case CSSPropertyWebkitMarginBefore
:
179 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, marginShorthand());
180 case CSSPropertyWebkitMarginAfter
:
181 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, marginShorthand());
182 case CSSPropertyWebkitPaddingEnd
:
183 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, paddingShorthand());
184 case CSSPropertyWebkitPaddingStart
:
185 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, paddingShorthand());
186 case CSSPropertyWebkitPaddingBefore
:
187 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, paddingShorthand());
188 case CSSPropertyWebkitPaddingAfter
:
189 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, paddingShorthand());
190 case CSSPropertyWebkitBorderEnd
:
191 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, borderDirections());
192 case CSSPropertyWebkitBorderStart
:
193 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, borderDirections());
194 case CSSPropertyWebkitBorderBefore
:
195 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, borderDirections());
196 case CSSPropertyWebkitBorderAfter
:
197 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, borderDirections());
198 case CSSPropertyWebkitBorderEndColor
:
199 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, borderColorShorthand());
200 case CSSPropertyWebkitBorderStartColor
:
201 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, borderColorShorthand());
202 case CSSPropertyWebkitBorderBeforeColor
:
203 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, borderColorShorthand());
204 case CSSPropertyWebkitBorderAfterColor
:
205 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, borderColorShorthand());
206 case CSSPropertyWebkitBorderEndStyle
:
207 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, borderStyleShorthand());
208 case CSSPropertyWebkitBorderStartStyle
:
209 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, borderStyleShorthand());
210 case CSSPropertyWebkitBorderBeforeStyle
:
211 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, borderStyleShorthand());
212 case CSSPropertyWebkitBorderAfterStyle
:
213 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, borderStyleShorthand());
214 case CSSPropertyWebkitBorderEndWidth
:
215 return resolveToPhysicalProperty(direction
, writingMode
, EndSide
, borderWidthShorthand());
216 case CSSPropertyWebkitBorderStartWidth
:
217 return resolveToPhysicalProperty(direction
, writingMode
, StartSide
, borderWidthShorthand());
218 case CSSPropertyWebkitBorderBeforeWidth
:
219 return resolveToPhysicalProperty(direction
, writingMode
, BeforeSide
, borderWidthShorthand());
220 case CSSPropertyWebkitBorderAfterWidth
:
221 return resolveToPhysicalProperty(direction
, writingMode
, AfterSide
, borderWidthShorthand());
222 case CSSPropertyWebkitLogicalWidth
: {
223 const CSSPropertyID properties
[2] = { CSSPropertyWidth
, CSSPropertyHeight
};
224 return resolveToPhysicalProperty(writingMode
, LogicalWidth
, properties
);
226 case CSSPropertyWebkitLogicalHeight
: {
227 const CSSPropertyID properties
[2] = { CSSPropertyWidth
, CSSPropertyHeight
};
228 return resolveToPhysicalProperty(writingMode
, LogicalHeight
, properties
);
230 case CSSPropertyWebkitMinLogicalWidth
: {
231 const CSSPropertyID properties
[2] = { CSSPropertyMinWidth
, CSSPropertyMinHeight
};
232 return resolveToPhysicalProperty(writingMode
, LogicalWidth
, properties
);
234 case CSSPropertyWebkitMinLogicalHeight
: {
235 const CSSPropertyID properties
[2] = { CSSPropertyMinWidth
, CSSPropertyMinHeight
};
236 return resolveToPhysicalProperty(writingMode
, LogicalHeight
, properties
);
238 case CSSPropertyWebkitMaxLogicalWidth
: {
239 const CSSPropertyID properties
[2] = { CSSPropertyMaxWidth
, CSSPropertyMaxHeight
};
240 return resolveToPhysicalProperty(writingMode
, LogicalWidth
, properties
);
242 case CSSPropertyWebkitMaxLogicalHeight
: {
243 const CSSPropertyID properties
[2] = { CSSPropertyMaxWidth
, CSSPropertyMaxHeight
};
244 return resolveToPhysicalProperty(writingMode
, LogicalHeight
, properties
);
251 bool CSSProperty::isAffectedByAllProperty(CSSPropertyID propertyID
)
253 if (propertyID
== CSSPropertyAll
)
256 if (!CSSPropertyMetadata::isEnabledProperty(propertyID
))
259 // all shorthand spec says:
260 // The all property is a shorthand that resets all CSS properties except
261 // direction and unicode-bidi. It only accepts the CSS-wide keywords.
262 // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
263 // So CSSPropertyUnicodeBidi and CSSPropertyDirection are not
264 // affected by all property.
265 return propertyID
!= CSSPropertyUnicodeBidi
&& propertyID
!= CSSPropertyDirection
;
268 bool CSSProperty::operator==(const CSSProperty
& other
) const
270 return m_value
->equals(*other
.m_value
) && isImportant() == other
.isImportant();