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

Side by Side Diff: third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp

Issue 2323633002: Implement animation tainted custom property values (Closed)
Patch Set: bigger fallback value Created 4 years, 2 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/css/resolver/CSSVariableResolver.h" 5 #include "core/css/resolver/CSSVariableResolver.h"
6 6
7 #include "core/CSSPropertyNames.h" 7 #include "core/CSSPropertyNames.h"
8 #include "core/CSSValueKeywords.h" 8 #include "core/CSSValueKeywords.h"
9 #include "core/StyleBuilderFunctions.h" 9 #include "core/StyleBuilderFunctions.h"
10 #include "core/StylePropertyShorthand.h" 10 #include "core/StylePropertyShorthand.h"
11 #include "core/css/CSSPendingSubstitutionValue.h" 11 #include "core/css/CSSPendingSubstitutionValue.h"
12 #include "core/css/CSSUnsetValue.h" 12 #include "core/css/CSSUnsetValue.h"
13 #include "core/css/CSSVariableData.h" 13 #include "core/css/CSSVariableData.h"
14 #include "core/css/CSSVariableReferenceValue.h" 14 #include "core/css/CSSVariableReferenceValue.h"
15 #include "core/css/PropertyRegistry.h" 15 #include "core/css/PropertyRegistry.h"
16 #include "core/css/parser/CSSParserToken.h" 16 #include "core/css/parser/CSSParserToken.h"
17 #include "core/css/parser/CSSParserTokenRange.h" 17 #include "core/css/parser/CSSParserTokenRange.h"
18 #include "core/css/parser/CSSPropertyParser.h" 18 #include "core/css/parser/CSSPropertyParser.h"
19 #include "core/css/resolver/StyleBuilder.h" 19 #include "core/css/resolver/StyleBuilder.h"
20 #include "core/css/resolver/StyleBuilderConverter.h" 20 #include "core/css/resolver/StyleBuilderConverter.h"
21 #include "core/css/resolver/StyleResolverState.h" 21 #include "core/css/resolver/StyleResolverState.h"
22 #include "core/style/StyleInheritedVariables.h" 22 #include "core/style/StyleInheritedVariables.h"
23 #include "core/style/StyleNonInheritedVariables.h" 23 #include "core/style/StyleNonInheritedVariables.h"
24 #include "wtf/Vector.h" 24 #include "wtf/Vector.h"
25 25
26 namespace blink { 26 namespace blink {
27 27
28 bool CSSVariableResolver::resolveFallback(CSSParserTokenRange range, 28 bool CSSVariableResolver::resolveFallback(CSSParserTokenRange range,
29 Vector<CSSParserToken>& result) { 29 bool omitAnimationTainted,
30 Vector<CSSParserToken>& result,
31 bool& resultIsAnimationTainted) {
30 if (range.atEnd()) 32 if (range.atEnd())
31 return false; 33 return false;
32 ASSERT(range.peek().type() == CommaToken); 34 ASSERT(range.peek().type() == CommaToken);
33 range.consume(); 35 range.consume();
34 return resolveTokenRange(range, result); 36 return resolveTokenRange(range, omitAnimationTainted, result,
37 resultIsAnimationTainted);
35 } 38 }
36 39
37 CSSVariableData* CSSVariableResolver::valueForCustomProperty( 40 CSSVariableData* CSSVariableResolver::valueForCustomProperty(
38 AtomicString name) { 41 AtomicString name) {
39 if (m_variablesSeen.contains(name)) { 42 if (m_variablesSeen.contains(name)) {
40 m_cycleStartPoints.add(name); 43 m_cycleStartPoints.add(name);
41 return nullptr; 44 return nullptr;
42 } 45 }
43 46
44 DCHECK(m_registry || !RuntimeEnabledFeatures::cssVariables2Enabled()); 47 DCHECK(m_registry || !RuntimeEnabledFeatures::cssVariables2Enabled());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 if (!newVariableData) 86 if (!newVariableData)
84 return registration->initialVariableData(); 87 return registration->initialVariableData();
85 return newVariableData.get(); 88 return newVariableData.get();
86 } 89 }
87 90
88 PassRefPtr<CSSVariableData> CSSVariableResolver::resolveCustomProperty( 91 PassRefPtr<CSSVariableData> CSSVariableResolver::resolveCustomProperty(
89 AtomicString name, 92 AtomicString name,
90 const CSSVariableData& variableData) { 93 const CSSVariableData& variableData) {
91 ASSERT(variableData.needsVariableResolution()); 94 ASSERT(variableData.needsVariableResolution());
92 95
96 bool omitAnimationTainted = false;
97 bool isAnimationTainted = variableData.isAnimationTainted();
93 Vector<CSSParserToken> tokens; 98 Vector<CSSParserToken> tokens;
94 m_variablesSeen.add(name); 99 m_variablesSeen.add(name);
95 bool success = resolveTokenRange(variableData.tokens(), tokens); 100 bool success = resolveTokenRange(variableData.tokens(), omitAnimationTainted,
101 tokens, isAnimationTainted);
96 m_variablesSeen.remove(name); 102 m_variablesSeen.remove(name);
97 103
98 // The old variable data holds onto the backing string the new resolved CSSVar iableData 104 // The old variable data holds onto the backing string the new resolved CSSVar iableData
99 // relies on. Ensure it will live beyond us overwriting the RefPtr in StyleInh eritedVariables. 105 // relies on. Ensure it will live beyond us overwriting the RefPtr in StyleInh eritedVariables.
100 ASSERT(variableData.refCount() > 1); 106 ASSERT(variableData.refCount() > 1);
101 107
102 if (!success || !m_cycleStartPoints.isEmpty()) { 108 if (!success || !m_cycleStartPoints.isEmpty()) {
103 m_cycleStartPoints.remove(name); 109 m_cycleStartPoints.remove(name);
104 return nullptr; 110 return nullptr;
105 } 111 }
106 return CSSVariableData::createResolved(tokens, variableData); 112 return CSSVariableData::createResolved(tokens, variableData,
113 isAnimationTainted);
107 } 114 }
108 115
109 bool CSSVariableResolver::resolveVariableReference( 116 bool CSSVariableResolver::resolveVariableReference(
110 CSSParserTokenRange range, 117 CSSParserTokenRange range,
111 Vector<CSSParserToken>& result) { 118 bool omitAnimationTainted,
119 Vector<CSSParserToken>& result,
120 bool& resultIsAnimationTainted) {
112 range.consumeWhitespace(); 121 range.consumeWhitespace();
113 ASSERT(range.peek().type() == IdentToken); 122 ASSERT(range.peek().type() == IdentToken);
114 AtomicString variableName = 123 AtomicString variableName =
115 range.consumeIncludingWhitespace().value().toAtomicString(); 124 range.consumeIncludingWhitespace().value().toAtomicString();
116 ASSERT(range.atEnd() || (range.peek().type() == CommaToken)); 125 ASSERT(range.atEnd() || (range.peek().type() == CommaToken));
117 126
118 CSSVariableData* variableData = valueForCustomProperty(variableName); 127 CSSVariableData* variableData = valueForCustomProperty(variableName);
119 if (!variableData) 128 if (!variableData) {
120 return resolveFallback(range, result); 129 return resolveFallback(range, omitAnimationTainted, result,
130 resultIsAnimationTainted);
131 }
121 132
122 result.appendVector(variableData->tokens()); 133 if (!omitAnimationTainted || !variableData->isAnimationTainted()) {
alancutter (OOO until 2018) 2016/10/05 07:46:40 Negate this and return so it reads better and does
alancutter (OOO until 2018) 2016/10/06 01:25:32 Done.
134 result.appendVector(variableData->tokens());
135 resultIsAnimationTainted |= variableData->isAnimationTainted();
136 } else {
137 // TODO(alancutter): Append the registered initial custom property value.
alancutter (OOO until 2018) 2016/10/05 07:46:40 This should be calling resolveFallback instead of
alancutter (OOO until 2018) 2016/10/06 01:25:32 Done.
138 }
139
123 Vector<CSSParserToken> trash; 140 Vector<CSSParserToken> trash;
124 resolveFallback(range, trash); 141 bool trashIsAnimationTainted;
142 resolveFallback(range, omitAnimationTainted, trash, trashIsAnimationTainted);
125 return true; 143 return true;
126 } 144 }
127 145
128 void CSSVariableResolver::resolveApplyAtRule(CSSParserTokenRange& range, 146 void CSSVariableResolver::resolveApplyAtRule(CSSParserTokenRange& range,
129 Vector<CSSParserToken>& result) { 147 Vector<CSSParserToken>& result) {
130 DCHECK(range.peek().type() == AtKeywordToken && 148 DCHECK(range.peek().type() == AtKeywordToken &&
131 equalIgnoringASCIICase(range.peek().value(), "apply")); 149 equalIgnoringASCIICase(range.peek().value(), "apply"));
132 range.consumeIncludingWhitespace(); 150 range.consumeIncludingWhitespace();
133 const CSSParserToken& variableName = range.consumeIncludingWhitespace(); 151 const CSSParserToken& variableName = range.consumeIncludingWhitespace();
134 // TODO(timloh): Should we actually be consuming this? 152 // TODO(timloh): Should we actually be consuming this?
(...skipping 11 matching lines...) Expand all
146 return; 164 return;
147 CSSParserTokenRange ruleContents = rule.consumeBlock(); 165 CSSParserTokenRange ruleContents = rule.consumeBlock();
148 rule.consumeWhitespace(); 166 rule.consumeWhitespace();
149 if (!rule.atEnd()) 167 if (!rule.atEnd())
150 return; 168 return;
151 169
152 result.appendRange(ruleContents.begin(), ruleContents.end()); 170 result.appendRange(ruleContents.begin(), ruleContents.end());
153 } 171 }
154 172
155 bool CSSVariableResolver::resolveTokenRange(CSSParserTokenRange range, 173 bool CSSVariableResolver::resolveTokenRange(CSSParserTokenRange range,
156 Vector<CSSParserToken>& result) { 174 bool omitAnimationTainted,
175 Vector<CSSParserToken>& result,
176 bool& resultIsAnimationTainted) {
157 bool success = true; 177 bool success = true;
158 while (!range.atEnd()) { 178 while (!range.atEnd()) {
159 if (range.peek().functionId() == CSSValueVar) { 179 if (range.peek().functionId() == CSSValueVar) {
160 success &= resolveVariableReference(range.consumeBlock(), result); 180 success &=
181 resolveVariableReference(range.consumeBlock(), omitAnimationTainted,
182 result, resultIsAnimationTainted);
161 } else if (range.peek().type() == AtKeywordToken && 183 } else if (range.peek().type() == AtKeywordToken &&
162 equalIgnoringASCIICase(range.peek().value(), "apply") && 184 equalIgnoringASCIICase(range.peek().value(), "apply") &&
163 RuntimeEnabledFeatures::cssApplyAtRulesEnabled()) { 185 RuntimeEnabledFeatures::cssApplyAtRulesEnabled()) {
164 resolveApplyAtRule(range, result); 186 resolveApplyAtRule(range, result);
165 } else { 187 } else {
166 result.append(range.consume()); 188 result.append(range.consume());
167 } 189 }
168 } 190 }
169 return success; 191 return success;
170 } 192 }
171 193
172 const CSSValue* CSSVariableResolver::resolveVariableReferences( 194 const CSSValue* CSSVariableResolver::resolveVariableReferences(
173 const StyleResolverState& state, 195 const StyleResolverState& state,
174 CSSPropertyID id, 196 CSSPropertyID id,
175 const CSSValue& value) { 197 const CSSValue& value,
198 bool omitAnimationTainted) {
176 ASSERT(!isShorthandProperty(id)); 199 ASSERT(!isShorthandProperty(id));
177 200
178 if (value.isPendingSubstitutionValue()) 201 if (value.isPendingSubstitutionValue()) {
179 return resolvePendingSubstitutions(state, id, 202 return resolvePendingSubstitutions(
180 toCSSPendingSubstitutionValue(value)); 203 state, id, toCSSPendingSubstitutionValue(value), omitAnimationTainted);
204 }
181 205
182 if (value.isVariableReferenceValue()) 206 if (value.isVariableReferenceValue()) {
183 return resolveVariableReferences(state, id, 207 return resolveVariableReferences(
184 toCSSVariableReferenceValue(value)); 208 state, id, toCSSVariableReferenceValue(value), omitAnimationTainted);
209 }
185 210
186 NOTREACHED(); 211 NOTREACHED();
187 return nullptr; 212 return nullptr;
188 } 213 }
189 214
190 const CSSValue* CSSVariableResolver::resolveVariableReferences( 215 const CSSValue* CSSVariableResolver::resolveVariableReferences(
191 const StyleResolverState& state, 216 const StyleResolverState& state,
192 CSSPropertyID id, 217 CSSPropertyID id,
193 const CSSVariableReferenceValue& value) { 218 const CSSVariableReferenceValue& value,
219 bool omitAnimationTainted) {
194 CSSVariableResolver resolver(state); 220 CSSVariableResolver resolver(state);
195 Vector<CSSParserToken> tokens; 221 Vector<CSSParserToken> tokens;
196 if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) 222 bool isAnimationTainted = false;
223 if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(),
224 omitAnimationTainted, tokens,
225 isAnimationTainted))
197 return CSSUnsetValue::create(); 226 return CSSUnsetValue::create();
198 const CSSValue* result = 227 const CSSValue* result =
199 CSSPropertyParser::parseSingleValue(id, tokens, strictCSSParserContext()); 228 CSSPropertyParser::parseSingleValue(id, tokens, strictCSSParserContext());
200 if (!result) 229 if (!result)
201 return CSSUnsetValue::create(); 230 return CSSUnsetValue::create();
202 return result; 231 return result;
203 } 232 }
204 233
205 const CSSValue* CSSVariableResolver::resolvePendingSubstitutions( 234 const CSSValue* CSSVariableResolver::resolvePendingSubstitutions(
206 const StyleResolverState& state, 235 const StyleResolverState& state,
207 CSSPropertyID id, 236 CSSPropertyID id,
208 const CSSPendingSubstitutionValue& pendingValue) { 237 const CSSPendingSubstitutionValue& pendingValue,
238 bool omitAnimationTainted) {
209 // Longhands from shorthand references follow this path. 239 // Longhands from shorthand references follow this path.
210 HeapHashMap<CSSPropertyID, Member<const CSSValue>>& propertyCache = 240 HeapHashMap<CSSPropertyID, Member<const CSSValue>>& propertyCache =
211 state.parsedPropertiesForPendingSubstitutionCache(pendingValue); 241 state.parsedPropertiesForPendingSubstitutionCache(pendingValue);
212 242
213 const CSSValue* value = propertyCache.get(id); 243 const CSSValue* value = propertyCache.get(id);
214 if (!value) { 244 if (!value) {
215 // TODO(timloh): We shouldn't retry this for all longhands if the shorthand ends up invalid 245 // TODO(timloh): We shouldn't retry this for all longhands if the shorthand ends up invalid
216 CSSVariableReferenceValue* shorthandValue = pendingValue.shorthandValue(); 246 CSSVariableReferenceValue* shorthandValue = pendingValue.shorthandValue();
217 CSSPropertyID shorthandPropertyId = pendingValue.shorthandPropertyId(); 247 CSSPropertyID shorthandPropertyId = pendingValue.shorthandPropertyId();
218 248
219 CSSVariableResolver resolver(state); 249 CSSVariableResolver resolver(state);
220 250
221 Vector<CSSParserToken> tokens; 251 Vector<CSSParserToken> tokens;
252 bool isAnimationTainted = false;
222 if (resolver.resolveTokenRange( 253 if (resolver.resolveTokenRange(
223 shorthandValue->variableDataValue()->tokens(), tokens)) { 254 shorthandValue->variableDataValue()->tokens(), omitAnimationTainted,
255 tokens, isAnimationTainted)) {
224 CSSParserContext context(HTMLStandardMode, 0); 256 CSSParserContext context(HTMLStandardMode, 0);
225 257
226 HeapVector<CSSProperty, 256> parsedProperties; 258 HeapVector<CSSProperty, 256> parsedProperties;
227 259
228 if (CSSPropertyParser::parseValue( 260 if (CSSPropertyParser::parseValue(
229 shorthandPropertyId, false, CSSParserTokenRange(tokens), context, 261 shorthandPropertyId, false, CSSParserTokenRange(tokens), context,
230 parsedProperties, StyleRule::RuleType::Style)) { 262 parsedProperties, StyleRule::RuleType::Style)) {
231 unsigned parsedPropertiesCount = parsedProperties.size(); 263 unsigned parsedPropertiesCount = parsedProperties.size();
232 for (unsigned i = 0; i < parsedPropertiesCount; ++i) { 264 for (unsigned i = 0; i < parsedPropertiesCount; ++i) {
233 propertyCache.set(parsedProperties[i].id(), 265 propertyCache.set(parsedProperties[i].id(),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 : m_styleResolverState(state), 300 : m_styleResolverState(state),
269 m_inheritedVariables(state.style()->inheritedVariables()), 301 m_inheritedVariables(state.style()->inheritedVariables()),
270 m_nonInheritedVariables(state.style()->nonInheritedVariables()), 302 m_nonInheritedVariables(state.style()->nonInheritedVariables()),
271 m_registry(state.document().propertyRegistry()) {} 303 m_registry(state.document().propertyRegistry()) {}
272 304
273 DEFINE_TRACE(CSSVariableResolver) { 305 DEFINE_TRACE(CSSVariableResolver) {
274 visitor->trace(m_registry); 306 visitor->trace(m_registry);
275 } 307 }
276 308
277 } // namespace blink 309 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698