Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

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: move functions around :| Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 blink {
15
16 namespace {
17
18 bool isValidCueStyleProperty(CSSPropertyID property)
esprehn 2014/07/21 18:50:34 static, get rid of the anonymous namespace.
Timothy Loh 2014/07/22 14:32:48 Done.
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)
esprehn 2014/07/21 18:50:34 static
Timothy Loh 2014/07/22 14:32:48 Done.
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)
esprehn 2014/07/21 18:50:34 static
Timothy Loh 2014/07/22 14:32:48 Done.
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 addMatchResultInternal(matchResult, false, 0, matchResult.matchedProperties. size() - 1, CSSPropertyDirection, CSSPropertyWebkitWritingMode);
esprehn 2014/07/21 18:50:34 Can we get rid of this boolean argument?
Timothy Loh 2014/07/22 14:32:48 The MatchResult stores declarations in the order (
258 addMatchResultInternal(matchResult, true, matchResult.ranges.firstAuthorRule , matchResult.ranges.lastAuthorRule, CSSPropertyDirection, CSSPropertyWebkitWrit ingMode);
259 addMatchResultInternal(matchResult, true, matchResult.ranges.firstUARule, ma tchResult.ranges.lastUARule, CSSPropertyDirection, CSSPropertyWebkitWritingMode) ;
260 applyValues(CSSPropertyDirection, CSSPropertyWebkitWritingMode);
261 direction = state.style()->direction();
262 writingMode = state.style()->writingMode();
263 }
264
265 void CascadedValues::addMatchResult(const MatchResult& matchResult, bool isImpor tant, int firstIndex, int lastIndex)
266 {
267 COMPILE_ASSERT(CSSPropertyColor == CSSPropertyWebkitWritingMode + 1, CSS_col or_is_after_super_high_priority);
268 addMatchResultInternal(matchResult, isImportant, firstIndex, lastIndex, CSSP ropertyColor, convertToCSSPropertyID(lastCSSProperty));
269 }
270
271 void CascadedValues::addMatchResultInternal(const MatchResult& matchResult, bool isImportant, int firstIndex, int lastIndex, CSSPropertyID firstId, CSSPropertyI D lastId)
272 {
273 if (firstIndex == -1)
274 return;
275
276 for (int i = firstIndex; i <= lastIndex; ++i) {
277 const MatchedProperties& matchedProperties = matchResult.matchedProperti es[i];
278 SelectorChecker::LinkMatchMask linkMatchType = SelectorChecker::MatchLin k;
279 if (state.style()->insideLink())
280 linkMatchType = static_cast<SelectorChecker::LinkMatchMask>(matchedP roperties.m_types.linkMatchType);
281 addStylePropertySet(matchedProperties.properties.get(), matchResult.matc hedRules[i], isImportant, firstId, lastId, static_cast<PropertyWhitelistType>(ma tchedProperties.m_types.whitelistType), linkMatchType);
282 }
283 }
284
285 void CascadedValues::addStylePropertySet(const StylePropertySet* properties, con st StyleRule* rule, bool isImportant, CSSPropertyID first, CSSPropertyID last, P ropertyWhitelistType propertyWhitelistType, SelectorChecker::LinkMatchMask linkM atchType)
286 {
287 unsigned propertyCount = properties->propertyCount();
288 for (unsigned i = 0; i < propertyCount; ++i) {
289 StylePropertySet::PropertyReference current = properties->propertyAt(i);
290 if (isImportant != current.isImportant())
291 continue;
292
293 CSSPropertyID property = current.id();
294 if (property < first || property > last)
295 continue;
296
297 // FIXME: We should check the whitelist, otherwise we might run into
298 // problems with e.g. foo:first-letter { all: inherit; }
299 if (property == CSSPropertyAll) {
300 addAllProperty(current.value(), linkMatchType);
301 continue;
302 }
303
304 if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStylePro perty(property))
305 continue;
306 if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFir stLetterStyleProperty(property))
307 continue;
308 addValue(current.id(), current.value(), rule, linkMatchType);
309 }
310 }
311
312 void CascadedValues::addValue(CSSPropertyID property, CSSValue* value, const Sty leRule* rule, SelectorChecker::LinkMatchMask linkMatchType)
313 {
314 property = resolveProperty(property, direction, writingMode);
315
316 if (property == CSSPropertyInternalCallback) {
317 ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValue ID() == CSSValueInternalPresence);
318 state.style()->addCallbackSelector(rule->selectorList().selectorsText()) ;
319 return;
320 }
321
322 // Shorthands that are not expanded in the parser need special handling here .
323 // The shorthand property occurs earlier in CSSPropertyNames.in than its
324 // longhands so we can cascade properly. If a longhand value is explicitly
325 // set, with higher priority than the shorthand, then the value computed
326 // from the shorthand will be overriden.
327
328 // FIXME: font should always be expanded by the parser; crbug.com/353932
329 if (property == CSSPropertyFont) {
330 values[CSSPropertyLineHeight - firstCSSProperty] = nullptr;
esprehn 2014/07/21 18:50:34 Why are you always subtracting backwards? I think
Timothy Loh 2014/07/22 14:32:48 Done.
331 values[CSSPropertyFontStyle - firstCSSProperty] = nullptr;
332 values[CSSPropertyFontFamily - firstCSSProperty] = nullptr;
333 values[CSSPropertyFontVariant - firstCSSProperty] = nullptr;
334 values[CSSPropertyFontWeight - firstCSSProperty] = nullptr;
335 values[CSSPropertyFontStyle - firstCSSProperty] = nullptr;
336 values[CSSPropertyFontSize - firstCSSProperty] = nullptr;
337 }
338
339 // -webkit-border-image sometimes also sets border-*-width, but properly
340 // cascading this requires too much effort
341 if (property == CSSPropertyWebkitBorderImage) {
342 values[CSSPropertyBorderImageSource - firstCSSProperty] = nullptr;
343 values[CSSPropertyBorderImageSlice - firstCSSProperty] = nullptr;
344 values[CSSPropertyBorderImageWidth - firstCSSProperty] = nullptr;
345 values[CSSPropertyBorderImageOutset - firstCSSProperty] = nullptr;
346 values[CSSPropertyBorderImageRepeat - firstCSSProperty] = nullptr;
347 }
348
349 if (linkMatchType & SelectorChecker::MatchLink)
350 values[property - firstCSSProperty] = value;
351 if (linkMatchType & SelectorChecker::MatchVisited)
352 visitedLinkValues[property - firstCSSProperty] = value;
353 }
354
355 void CascadedValues::addAllProperty(CSSValue* value, SelectorChecker::LinkMatchM ask linkMatchType)
356 {
357 if (!value->isInitialValue() && !value->isInheritedValue()) {
358 ASSERT(value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValue ID() == CSSValueUnset);
359 value = nullptr;
360 }
361
362 for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
363 CSSPropertyID property = convertToCSSPropertyID(i);
364 if (CSSProperty::isAffectedByAllProperty(property))
365 addValue(property, value, nullptr, linkMatchType);
366 }
367 }
368
369 void CascadedValues::applyValues(CSSPropertyID first, CSSPropertyID last, bool i nheritedOnly)
370 {
371 for (int i = first - firstCSSProperty; i <= last - firstCSSProperty; i++) {
372 CSSPropertyID property = convertToCSSPropertyID(i + firstCSSProperty);
373 if (inheritedOnly && !CSSProperty::isInheritedProperty(property))
374 continue;
375 if (values[i])
376 StyleBuilder::applyProperty(property, state, values[i]);
377 if (visitedLinkValues[i]) {
378 state.setApplyPropertyToRegularStyle(false);
379 state.setApplyPropertyToVisitedLinkStyle(true);
380 StyleBuilder::applyProperty(property, state, visitedLinkValues[i]);
381 state.setApplyPropertyToRegularStyle(true);
382 state.setApplyPropertyToVisitedLinkStyle(false);
383 }
384 }
385 }
386
387 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698