OLD | NEW |
---|---|
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/parser/CSSParserToken.h" | 16 #include "core/css/parser/CSSParserToken.h" |
16 #include "core/css/parser/CSSParserTokenRange.h" | 17 #include "core/css/parser/CSSParserTokenRange.h" |
17 #include "core/css/parser/CSSPropertyParser.h" | 18 #include "core/css/parser/CSSPropertyParser.h" |
18 #include "core/css/resolver/StyleBuilder.h" | 19 #include "core/css/resolver/StyleBuilder.h" |
20 #include "core/css/resolver/StyleBuilderConverter.h" | |
19 #include "core/css/resolver/StyleResolverState.h" | 21 #include "core/css/resolver/StyleResolverState.h" |
20 #include "core/style/StyleVariableData.h" | 22 #include "core/style/StyleVariableData.h" |
21 #include "wtf/Vector.h" | 23 #include "wtf/Vector.h" |
22 | 24 |
23 namespace blink { | 25 namespace blink { |
24 | 26 |
25 bool CSSVariableResolver::resolveFallback(CSSParserTokenRange range, Vector<CSSP arserToken>& result) | 27 bool CSSVariableResolver::resolveFallback(CSSParserTokenRange range, Vector<CSSP arserToken>& result) |
26 { | 28 { |
27 if (range.atEnd()) | 29 if (range.atEnd()) |
28 return false; | 30 return false; |
29 ASSERT(range.peek().type() == CommaToken); | 31 ASSERT(range.peek().type() == CommaToken); |
30 range.consume(); | 32 range.consume(); |
31 return resolveTokenRange(range, result); | 33 return resolveTokenRange(range, result); |
32 } | 34 } |
33 | 35 |
34 CSSVariableData* CSSVariableResolver::valueForCustomProperty(AtomicString name) | 36 CSSVariableData* CSSVariableResolver::valueForCustomProperty(AtomicString name) |
35 { | 37 { |
38 // TODO(timloh): Registered properties shouldn't return nullptr in failure | |
39 // cases (aside from cycles?), but instead return the initial/inherited valu e. | |
36 if (m_variablesSeen.contains(name)) { | 40 if (m_variablesSeen.contains(name)) { |
37 m_cycleStartPoints.add(name); | 41 m_cycleStartPoints.add(name); |
38 return nullptr; | 42 return nullptr; |
39 } | 43 } |
40 | 44 |
41 if (!m_styleVariableData) | 45 if (!m_styleVariableData) |
42 return nullptr; | 46 return nullptr; |
43 CSSVariableData* variableData = m_styleVariableData->getVariable(name); | 47 CSSVariableData* variableData = m_styleVariableData->getVariable(name); |
44 if (!variableData) | 48 if (!variableData) |
45 return nullptr; | 49 return nullptr; |
46 if (!variableData->needsVariableResolution()) | 50 if (!variableData->needsVariableResolution()) |
47 return variableData; | 51 return variableData; |
48 RefPtr<CSSVariableData> newVariableData = resolveCustomProperty(name, *varia bleData); | 52 RefPtr<CSSVariableData> newVariableData = resolveCustomProperty(name, *varia bleData); |
53 | |
54 DCHECK(m_registry || !RuntimeEnabledFeatures::cssVariables2Enabled()); | |
55 if (m_registry) { | |
56 const PropertyRegistry::Registration* registration = m_registry->registr ation(name); | |
57 if (registration) { | |
58 const CSSValue* parsedValue = nullptr; | |
59 if (newVariableData) { | |
60 parsedValue = newVariableData->parseForSyntax(registration->synt ax()); | |
61 if (parsedValue) | |
62 parsedValue = &StyleBuilderConverter::convertRegisteredPrope rtyValue(m_styleResolverState, *parsedValue); | |
63 else | |
64 newVariableData = nullptr; | |
65 } | |
66 m_styleVariableData->setVariable(name, newVariableData); | |
67 m_styleVariableData->setRegisteredInheritedProperty(name, parsedValu e); | |
68 return newVariableData.get(); | |
69 } | |
70 } | |
71 | |
49 m_styleVariableData->setVariable(name, newVariableData); | 72 m_styleVariableData->setVariable(name, newVariableData); |
50 return newVariableData.get(); | 73 return newVariableData.get(); |
51 } | 74 } |
52 | 75 |
53 PassRefPtr<CSSVariableData> CSSVariableResolver::resolveCustomProperty(AtomicStr ing name, const CSSVariableData& variableData) | 76 PassRefPtr<CSSVariableData> CSSVariableResolver::resolveCustomProperty(AtomicStr ing name, const CSSVariableData& variableData) |
54 { | 77 { |
55 ASSERT(variableData.needsVariableResolution()); | 78 ASSERT(variableData.needsVariableResolution()); |
56 | 79 |
57 Vector<CSSParserToken> tokens; | 80 Vector<CSSParserToken> tokens; |
58 m_variablesSeen.add(name); | 81 m_variablesSeen.add(name); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 result.append(range.consume()); | 150 result.append(range.consume()); |
128 } | 151 } |
129 } | 152 } |
130 return success; | 153 return success; |
131 } | 154 } |
132 | 155 |
133 const CSSValue* CSSVariableResolver::resolveVariableReferences(const StyleResolv erState& state, CSSPropertyID id, const CSSVariableReferenceValue& value) | 156 const CSSValue* CSSVariableResolver::resolveVariableReferences(const StyleResolv erState& state, CSSPropertyID id, const CSSVariableReferenceValue& value) |
134 { | 157 { |
135 ASSERT(!isShorthandProperty(id)); | 158 ASSERT(!isShorthandProperty(id)); |
136 | 159 |
137 CSSVariableResolver resolver(state.style()->variables()); | 160 CSSVariableResolver resolver(state); |
138 Vector<CSSParserToken> tokens; | 161 Vector<CSSParserToken> tokens; |
139 if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens) ) | 162 if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens) ) |
140 return CSSUnsetValue::create(); | 163 return CSSUnsetValue::create(); |
141 const CSSValue* result = CSSPropertyParser::parseSingleValue(id, tokens, str ictCSSParserContext()); | 164 const CSSValue* result = CSSPropertyParser::parseSingleValue(id, tokens, str ictCSSParserContext()); |
142 if (!result) | 165 if (!result) |
143 return CSSUnsetValue::create(); | 166 return CSSUnsetValue::create(); |
144 return result; | 167 return result; |
145 } | 168 } |
146 | 169 |
147 const CSSValue* CSSVariableResolver::resolvePendingSubstitutions(StyleResolverSt ate& state, CSSPropertyID id, const CSSPendingSubstitutionValue& pendingValue) | 170 const CSSValue* CSSVariableResolver::resolvePendingSubstitutions(StyleResolverSt ate& state, CSSPropertyID id, const CSSPendingSubstitutionValue& pendingValue) |
148 { | 171 { |
149 // Longhands from shorthand references follow this path. | 172 // Longhands from shorthand references follow this path. |
150 HeapHashMap<CSSPropertyID, Member<const CSSValue>>& propertyCache = state.pa rsedPropertiesForPendingSubstitution(pendingValue); | 173 HeapHashMap<CSSPropertyID, Member<const CSSValue>>& propertyCache = state.pa rsedPropertiesForPendingSubstitution(pendingValue); |
151 | 174 |
152 const CSSValue* value = propertyCache.get(id); | 175 const CSSValue* value = propertyCache.get(id); |
153 if (!value) { | 176 if (!value) { |
154 // TODO(timloh): We shouldn't retry this for all longhands if the shorth and ends up invalid | 177 // TODO(timloh): We shouldn't retry this for all longhands if the shorth and ends up invalid |
155 CSSVariableReferenceValue* shorthandValue = pendingValue.shorthandValue( ); | 178 CSSVariableReferenceValue* shorthandValue = pendingValue.shorthandValue( ); |
156 CSSPropertyID shorthandPropertyId = pendingValue.shorthandPropertyId(); | 179 CSSPropertyID shorthandPropertyId = pendingValue.shorthandPropertyId(); |
157 | 180 |
158 CSSVariableResolver resolver(state.style()->variables()); | 181 CSSVariableResolver resolver(state); |
159 | 182 |
160 Vector<CSSParserToken> tokens; | 183 Vector<CSSParserToken> tokens; |
161 if (resolver.resolveTokenRange(shorthandValue->variableDataValue()->toke ns(), tokens)) { | 184 if (resolver.resolveTokenRange(shorthandValue->variableDataValue()->toke ns(), tokens)) { |
162 CSSParserContext context(HTMLStandardMode, 0); | 185 CSSParserContext context(HTMLStandardMode, 0); |
163 | 186 |
164 HeapVector<CSSProperty, 256> parsedProperties; | 187 HeapVector<CSSProperty, 256> parsedProperties; |
165 | 188 |
166 if (CSSPropertyParser::parseValue(shorthandPropertyId, false, CSSPar serTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) { | 189 if (CSSPropertyParser::parseValue(shorthandPropertyId, false, CSSPar serTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) { |
167 unsigned parsedPropertiesCount = parsedProperties.size(); | 190 unsigned parsedPropertiesCount = parsedProperties.size(); |
168 for (unsigned i = 0; i < parsedPropertiesCount; ++i) { | 191 for (unsigned i = 0; i < parsedPropertiesCount; ++i) { |
169 propertyCache.set(parsedProperties[i].id(), parsedProperties [i].value()); | 192 propertyCache.set(parsedProperties[i].id(), parsedProperties [i].value()); |
170 } | 193 } |
171 } | 194 } |
172 } | 195 } |
173 value = propertyCache.get(id); | 196 value = propertyCache.get(id); |
174 } | 197 } |
175 | 198 |
176 if (value) | 199 if (value) |
177 return value; | 200 return value; |
178 | 201 |
179 return CSSUnsetValue::create(); | 202 return CSSUnsetValue::create(); |
180 } | 203 } |
181 | 204 |
182 | 205 |
183 void CSSVariableResolver::resolveVariableDefinitions(StyleVariableData* variable s) | 206 void CSSVariableResolver::resolveVariableDefinitions(const StyleResolverState& s tate) |
184 { | 207 { |
208 StyleVariableData* variables = state.style()->variables(); | |
185 if (!variables) | 209 if (!variables) |
186 return; | 210 return; |
187 | 211 |
188 CSSVariableResolver resolver(variables); | 212 CSSVariableResolver resolver(state); |
189 for (auto& variable : variables->m_data) { | 213 for (auto& variable : variables->m_data) |
190 if (variable.value && variable.value->needsVariableResolution()) | 214 resolver.valueForCustomProperty(variable.key); |
meade_UTC10
2016/09/06 04:52:06
This loop looks like it shouldn't do anything (whe
Timothy Loh
2016/09/06 08:21:17
Agreed, but I don't have any good names here (sugg
| |
191 variable.value = resolver.resolveCustomProperty(variable.key, *varia ble.value); | |
192 } | |
193 } | 215 } |
194 | 216 |
195 CSSVariableResolver::CSSVariableResolver(StyleVariableData* styleVariableData) | 217 CSSVariableResolver::CSSVariableResolver(const StyleResolverState& state) |
196 : m_styleVariableData(styleVariableData) | 218 : m_styleResolverState(state) |
219 , m_styleVariableData(state.style()->variables()) | |
220 , m_registry(state.document().propertyRegistry()) | |
197 { | 221 { |
198 } | 222 } |
199 | 223 |
224 DEFINE_TRACE(CSSVariableResolver) { visitor->trace(m_registry); } | |
225 | |
200 } // namespace blink | 226 } // namespace blink |
OLD | NEW |