Chromium Code Reviews

Side by Side Diff: Source/core/css/resolver/CascadedValues.cpp

Issue 350333003: Cascade declared property values instead of applying values on top of each other (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/css/resolver/CascadedValues.h"
7
8 #include "core/css/CSSValuePool.h"
9 #include "core/css/StylePropertySet.h"
10 #include "core/css/resolver/MatchResult.h"
11 #include "core/css/resolver/StyleBuilder.h"
12 #include "core/css/resolver/StyleResolverState.h"
13
14 namespace WebCore {
15
16 namespace {
17
18 bool isValidCueStyleProperty(CSSPropertyID property)
19 {
20 switch (property) {
21 case CSSPropertyBackground:
22 case CSSPropertyBackgroundAttachment:
23 case CSSPropertyBackgroundClip:
24 case CSSPropertyBackgroundColor:
25 case CSSPropertyBackgroundImage:
26 case CSSPropertyBackgroundOrigin:
27 case CSSPropertyBackgroundPosition:
28 case CSSPropertyBackgroundPositionX:
29 case CSSPropertyBackgroundPositionY:
30 case CSSPropertyBackgroundRepeat:
31 case CSSPropertyBackgroundRepeatX:
32 case CSSPropertyBackgroundRepeatY:
33 case CSSPropertyBackgroundSize:
34 case CSSPropertyColor:
35 case CSSPropertyFont:
36 case CSSPropertyFontFamily:
37 case CSSPropertyFontSize:
38 case CSSPropertyFontStyle:
39 case CSSPropertyFontVariant:
40 case CSSPropertyFontWeight:
41 case CSSPropertyLineHeight:
42 case CSSPropertyOpacity:
43 case CSSPropertyOutline:
44 case CSSPropertyOutlineColor:
45 case CSSPropertyOutlineOffset:
46 case CSSPropertyOutlineStyle:
47 case CSSPropertyOutlineWidth:
48 case CSSPropertyVisibility:
49 case CSSPropertyWhiteSpace:
50 // FIXME: 'text-decoration' shorthand to be handled when available.
51 // See https://chromiumcodereview.appspot.com/19516002 for details.
52 case CSSPropertyTextDecoration:
53 case CSSPropertyTextShadow:
54 case CSSPropertyBorderStyle:
55 return true;
56 case CSSPropertyTextDecorationLine:
57 case CSSPropertyTextDecorationStyle:
58 case CSSPropertyTextDecorationColor:
59 return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
60 default:
61 break;
62 }
63 return false;
64 }
65
66 bool isValidFirstLetterStyleProperty(CSSPropertyID property)
67 {
68 switch (property) {
69 // Valid ::first-letter properties listed in spec:
70 // http://www.w3.org/TR/css3-selectors/#application-in-css
71 case CSSPropertyBackgroundAttachment:
72 case CSSPropertyBackgroundBlendMode:
73 case CSSPropertyBackgroundClip:
74 case CSSPropertyBackgroundColor:
75 case CSSPropertyBackgroundImage:
76 case CSSPropertyBackgroundOrigin:
77 case CSSPropertyBackgroundPosition:
78 case CSSPropertyBackgroundPositionX:
79 case CSSPropertyBackgroundPositionY:
80 case CSSPropertyBackgroundRepeat:
81 case CSSPropertyBackgroundRepeatX:
82 case CSSPropertyBackgroundRepeatY:
83 case CSSPropertyBackgroundSize:
84 case CSSPropertyBorderBottomColor:
85 case CSSPropertyBorderBottomLeftRadius:
86 case CSSPropertyBorderBottomRightRadius:
87 case CSSPropertyBorderBottomStyle:
88 case CSSPropertyBorderBottomWidth:
89 case CSSPropertyBorderImageOutset:
90 case CSSPropertyBorderImageRepeat:
91 case CSSPropertyBorderImageSlice:
92 case CSSPropertyBorderImageSource:
93 case CSSPropertyBorderImageWidth:
94 case CSSPropertyBorderLeftColor:
95 case CSSPropertyBorderLeftStyle:
96 case CSSPropertyBorderLeftWidth:
97 case CSSPropertyBorderRightColor:
98 case CSSPropertyBorderRightStyle:
99 case CSSPropertyBorderRightWidth:
100 case CSSPropertyBorderTopColor:
101 case CSSPropertyBorderTopLeftRadius:
102 case CSSPropertyBorderTopRightRadius:
103 case CSSPropertyBorderTopStyle:
104 case CSSPropertyBorderTopWidth:
105 case CSSPropertyColor:
106 case CSSPropertyFloat:
107 case CSSPropertyFont:
108 case CSSPropertyFontFamily:
109 case CSSPropertyFontKerning:
110 case CSSPropertyFontSize:
111 case CSSPropertyFontStretch:
112 case CSSPropertyFontStyle:
113 case CSSPropertyFontVariant:
114 case CSSPropertyFontVariantLigatures:
115 case CSSPropertyFontWeight:
116 case CSSPropertyLetterSpacing:
117 case CSSPropertyLineHeight:
118 case CSSPropertyMarginBottom:
119 case CSSPropertyMarginLeft:
120 case CSSPropertyMarginRight:
121 case CSSPropertyMarginTop:
122 case CSSPropertyPaddingBottom:
123 case CSSPropertyPaddingLeft:
124 case CSSPropertyPaddingRight:
125 case CSSPropertyPaddingTop:
126 case CSSPropertyTextTransform:
127 case CSSPropertyVerticalAlign:
128 case CSSPropertyWebkitBackgroundClip:
129 case CSSPropertyWebkitBackgroundComposite:
130 case CSSPropertyWebkitBackgroundOrigin:
131 case CSSPropertyWebkitBackgroundSize:
132 case CSSPropertyWebkitBorderAfter:
133 case CSSPropertyWebkitBorderAfterColor:
134 case CSSPropertyWebkitBorderAfterStyle:
135 case CSSPropertyWebkitBorderAfterWidth:
136 case CSSPropertyWebkitBorderBefore:
137 case CSSPropertyWebkitBorderBeforeColor:
138 case CSSPropertyWebkitBorderBeforeStyle:
139 case CSSPropertyWebkitBorderBeforeWidth:
140 case CSSPropertyWebkitBorderEnd:
141 case CSSPropertyWebkitBorderEndColor:
142 case CSSPropertyWebkitBorderEndStyle:
143 case CSSPropertyWebkitBorderEndWidth:
144 case CSSPropertyWebkitBorderFit:
145 case CSSPropertyWebkitBorderHorizontalSpacing:
146 case CSSPropertyWebkitBorderImage:
147 case CSSPropertyWebkitBorderRadius:
148 case CSSPropertyWebkitBorderStart:
149 case CSSPropertyWebkitBorderStartColor:
150 case CSSPropertyWebkitBorderStartStyle:
151 case CSSPropertyWebkitBorderStartWidth:
152 case CSSPropertyWebkitBorderVerticalSpacing:
153 case CSSPropertyWebkitFontSmoothing:
154 case CSSPropertyWebkitMarginAfter:
155 case CSSPropertyWebkitMarginAfterCollapse:
156 case CSSPropertyWebkitMarginBefore:
157 case CSSPropertyWebkitMarginBeforeCollapse:
158 case CSSPropertyWebkitMarginBottomCollapse:
159 case CSSPropertyWebkitMarginCollapse:
160 case CSSPropertyWebkitMarginEnd:
161 case CSSPropertyWebkitMarginStart:
162 case CSSPropertyWebkitMarginTopCollapse:
163 case CSSPropertyWordSpacing:
164 return true;
165 case CSSPropertyTextDecorationColor:
166 case CSSPropertyTextDecorationLine:
167 case CSSPropertyTextDecorationStyle:
168 return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
169
170 // text-shadow added in text decoration spec:
171 // http://www.w3.org/TR/css-text-decor-3/#text-shadow-property
172 case CSSPropertyTextShadow:
173 // box-shadox added in CSS3 backgrounds spec:
174 // http://www.w3.org/TR/css3-background/#placement
175 case CSSPropertyBoxShadow:
176 case CSSPropertyWebkitBoxShadow:
177 // Properties that we currently support outside of spec.
178 case CSSPropertyWebkitLineBoxContain:
179 case CSSPropertyVisibility:
180 return true;
181
182 default:
183 return false;
184 }
185 }
186
187 // We want properties in their prefixed and non-prefixed variants to cascade
188 // together, so we map them to the same property before adding to the cascade.
189 CSSPropertyID resolveProperty(CSSPropertyID property, TextDirection direction, W ritingMode writingMode)
190 {
191 switch (property) {
192 case CSSPropertyWebkitBorderEndColor:
193 case CSSPropertyWebkitBorderBeforeStyle:
194 case CSSPropertyWebkitBorderEndStyle:
195 case CSSPropertyWebkitPaddingStart:
196 case CSSPropertyWebkitBorderStartWidth:
197 case CSSPropertyWebkitMaxLogicalWidth:
198 case CSSPropertyWebkitLogicalHeight:
199 case CSSPropertyWebkitMinLogicalWidth:
200 case CSSPropertyWebkitBorderBeforeWidth:
201 case CSSPropertyWebkitPaddingBefore:
202 case CSSPropertyWebkitBorderBeforeColor:
203 case CSSPropertyWebkitMarginEnd:
204 case CSSPropertyWebkitBorderAfterWidth:
205 case CSSPropertyWebkitMinLogicalHeight:
206 case CSSPropertyWebkitBorderEndWidth:
207 case CSSPropertyWebkitPaddingEnd:
208 case CSSPropertyWebkitLogicalWidth:
209 case CSSPropertyWebkitBorderAfterColor:
210 case CSSPropertyWebkitMaxLogicalHeight:
211 case CSSPropertyWebkitBorderStartColor:
212 case CSSPropertyWebkitBorderAfterStyle:
213 case CSSPropertyWebkitPaddingAfter:
214 case CSSPropertyWebkitBorderStartStyle:
215 case CSSPropertyWebkitMarginBefore:
216 case CSSPropertyWebkitMarginStart:
217 case CSSPropertyWebkitMarginAfter:
218 return CSSProperty::resolveDirectionAwareProperty(property, direction, w ritingMode);
219 case CSSPropertyWebkitBackfaceVisibility:
220 return CSSPropertyBackfaceVisibility;
221 case CSSPropertyWebkitBackgroundClip:
222 return CSSPropertyBackgroundClip;
223 case CSSPropertyWebkitBackgroundOrigin:
224 return CSSPropertyBackgroundOrigin;
225 case CSSPropertyWebkitBackgroundSize:
226 return CSSPropertyBackgroundSize;
227 case CSSPropertyWebkitBoxShadow:
228 return CSSPropertyBoxShadow;
229 case CSSPropertyWebkitTransform:
230 return CSSPropertyTransform;
231 case CSSPropertyWebkitTransformStyle:
232 return CSSPropertyTransformStyle;
233 case CSSPropertyWebkitPerspective:
234 return CSSPropertyPerspective;
235 case CSSPropertyWebkitPerspectiveOrigin:
236 return CSSPropertyPerspectiveOrigin;
237 // Used by editing when the css3 text decorations flag is off
238 case CSSPropertyTextDecoration:
239 ASSERT(!RuntimeEnabledFeatures::css3TextDecorationsEnabled());
240 return CSSPropertyTextDecorationLine;
241 // As per css3-text, word-wrap is an alias for overflow-wrap
242 case CSSPropertyWordWrap:
243 return CSSPropertyOverflowWrap;
244 default:
245 return property;
246 }
247 }
248
249 } // namespace
250
251 CascadedValues::CascadedValues(StyleResolverState& state, const MatchResult& mat chResult)
252 : state(state)
253 {
254 memset(values, 0, sizeof(values));
255 memset(visitedLinkValues, 0, sizeof(visitedLinkValues));
256
257 bool seenImportantDirection = false;
258 bool seenImportantWritingMode = false;
259 for (size_t i = 0; i < matchResult.matchedProperties.size(); ++i) {
andersr 2014/07/17 12:15:38 This code *seems* annoyingly redundant, since it d
Timothy Loh 2014/07/21 06:05:59 Done.
260 const StylePropertySet& properties = *matchResult.matchedProperties[i].p roperties;
261 unsigned propertyCount = properties.propertyCount();
262 for (size_t j = 0; j < propertyCount; ++j) {
263 StylePropertySet::PropertyReference current = properties.propertyAt( j);
264 if (current.id() == CSSPropertyDirection) {
265 if (seenImportantDirection && !current.isImportant())
266 continue;
267 seenImportantDirection = current.isImportant();
268 } else if (current.id() == CSSPropertyWebkitWritingMode) {
269 if (seenImportantWritingMode && !current.isImportant())
270 continue;
271 seenImportantWritingMode = current.isImportant();
272 } else {
273 continue;
274 }
275 StyleBuilder::applyProperty(current.id(), state, current.value());
276 }
277 }
278
279 direction = state.style()->direction();
280 writingMode = state.style()->writingMode();
281 }
282
283 void CascadedValues::addAllProperty(CSSValue* value, SelectorChecker::LinkMatchM ask linkMatchType)
284 {
285 if (!value->isInitialValue() && !value->isInheritedValue()) {
286 ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValue ID() == CSSValueUnset);
287 value = nullptr;
288 }
289
290 for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
291 CSSPropertyID property = static_cast<CSSPropertyID>(i);
292 if (CSSProperty::isAffectedByAllProperty(property))
293 addValue(property, value, nullptr, linkMatchType);
294 }
295 }
296
297 void CascadedValues::addValue(CSSPropertyID property, CSSValue* value, const Sty leRule* rule, SelectorChecker::LinkMatchMask linkMatchType)
298 {
299 property = resolveProperty(property, direction, writingMode);
300
301 if (property == CSSPropertyInternalCallback) {
302 ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValue ID() == CSSValueInternalPresence);
303 state.style()->addCallbackSelector(rule->selectorList().selectorsText()) ;
304 return;
305 }
306
307 // FIXME: font is a shorthand but system fonts are not currently expanded (c rbug.com/353932).
308 // For now, we explicitly clear the properties for which font is a shorthand
309 // and rely on font having a lower CSSPropertyID than these other properties .
310 if (property == CSSPropertyFont) {
311 values[CSSPropertyLineHeight - firstCSSProperty] = nullptr;
312 values[CSSPropertyFontStyle - firstCSSProperty] = nullptr;
313 values[CSSPropertyFontFamily - firstCSSProperty] = nullptr;
314 values[CSSPropertyFontVariant - firstCSSProperty] = nullptr;
315 values[CSSPropertyFontWeight - firstCSSProperty] = nullptr;
316 values[CSSPropertyFontStyle - firstCSSProperty] = nullptr;
317 values[CSSPropertyFontSize - firstCSSProperty] = nullptr;
318 }
319
320 // -webkit-border-image is a shorthand for the below properties but not
321 // expanded in the parser. It sometimes also sets border-*-width, but
322 // we'll not try too hard to support legacy properties
323 if (property == CSSPropertyWebkitBorderImage) {
324 values[CSSPropertyBorderImageSource - firstCSSProperty] = nullptr;
325 values[CSSPropertyBorderImageSlice - firstCSSProperty] = nullptr;
326 values[CSSPropertyBorderImageWidth - firstCSSProperty] = nullptr;
327 values[CSSPropertyBorderImageOutset - firstCSSProperty] = nullptr;
328 values[CSSPropertyBorderImageRepeat - firstCSSProperty] = nullptr;
329 }
330
331 if (linkMatchType & SelectorChecker::MatchLink)
332 values[property - firstCSSProperty] = value;
333 if (linkMatchType & SelectorChecker::MatchVisited)
334 visitedLinkValues[property - firstCSSProperty] = value;
335 }
336
337 void CascadedValues::addValues(const MatchResult& matchResult, bool isImportant, int startIndex, int endIndex)
338 {
339 if (startIndex == -1)
340 return;
341
342 for (int i = startIndex; i <= endIndex; ++i) {
343 const MatchedProperties& matchedProperties = matchResult.matchedProperti es[i];
344 SelectorChecker::LinkMatchMask linkMatchType = SelectorChecker::MatchLin k;
345 if (state.style()->insideLink())
346 linkMatchType = static_cast<SelectorChecker::LinkMatchMask>(matchedP roperties.m_types.linkMatchType);
347 addValues(matchedProperties.properties.get(), matchResult.matchedRules[i ], isImportant, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whi telistType), linkMatchType);
348 }
349 }
350
351 void CascadedValues::addValues(const StylePropertySet* properties, const StyleRu le* rule, bool isImportant, PropertyWhitelistType propertyWhitelistType, Selecto rChecker::LinkMatchMask linkMatchType)
352 {
353 unsigned propertyCount = properties->propertyCount();
354 for (unsigned i = 0; i < propertyCount; ++i) {
355 StylePropertySet::PropertyReference current = properties->propertyAt(i);
356 if (isImportant != current.isImportant())
357 continue;
358
359 CSSPropertyID property = current.id();
360
361 // FIXME: We should check the whitelist, otherwise we might run into
362 // problems with e.g. foo:first-letter { all: inherit; }
363 if (property == CSSPropertyAll) {
364 addAllProperty(current.value(), linkMatchType);
365 continue;
366 }
367
368 if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStylePro perty(property))
369 continue;
370 if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFir stLetterStyleProperty(property))
371 continue;
372 addValue(current.id(), current.value(), rule, linkMatchType);
373 }
374 }
375
376 void CascadedValues::applyValues(CSSPropertyID start, CSSPropertyID end, bool in heritedOnly)
andersr 2014/07/17 12:15:38 Is first/last more appropriate than start/end?
Timothy Loh 2014/07/21 06:05:59 Good idea; changed to first/last.
377 {
378 for (int i = start - firstCSSProperty; i <= end - firstCSSProperty; i++) {
379 CSSPropertyID property = static_cast<CSSPropertyID>(i + firstCSSProperty );
380 if (inheritedOnly && !CSSProperty::isInheritedProperty(property))
381 continue;
382 if (values[i])
383 StyleBuilder::applyProperty(property, state, values[i]);
384 if (visitedLinkValues[i]) {
385 state.setApplyPropertyToRegularStyle(false);
386 state.setApplyPropertyToVisitedLinkStyle(true);
387 StyleBuilder::applyProperty(property, state, visitedLinkValues[i]);
388 state.setApplyPropertyToRegularStyle(true);
389 state.setApplyPropertyToVisitedLinkStyle(false);
390 }
391 }
392 }
393
394 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/css/resolver/CascadedValues.h ('k') | Source/core/css/resolver/StyleBuilderCustom.cpp » ('j') | no next file with comments »

Powered by Google App Engine