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); |
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 |