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