Index: third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp |
diff --git a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp |
index ec3acf69db58bdd8cee5c2ddf59c8019e92de81f..47405f90588436f7d411e4038c95792cb5b3e9f0 100644 |
--- a/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp |
+++ b/third_party/WebKit/Source/core/css/resolver/CSSVariableResolver.cpp |
@@ -22,19 +22,17 @@ |
namespace blink { |
-void CSSVariableResolver::resolveFallback(CSSParserTokenRange range, |
- Vector<CSSParserToken>& result, CSSVariableResolver::ResolutionState& context) |
+bool CSSVariableResolver::resolveFallback(CSSParserTokenRange range, Vector<CSSParserToken>& result) |
{ |
- if (!range.atEnd()) { |
- range.consume(); |
- resolveVariableReferencesFromTokens(range, result, context); |
- } else { |
- context.success = false; |
- } |
+ if (range.atEnd()) |
+ return false; |
+ ASSERT(range.peek().type() == CommaToken); |
+ range.consume(); |
+ return resolveVariableReferencesFromTokens(range, result); |
} |
-void CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange range, |
- Vector<CSSParserToken>& result, CSSVariableResolver::ResolutionState& context) |
+bool CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange range, |
+ Vector<CSSParserToken>& result) |
{ |
Vector<CSSParserToken> trash; |
range.consumeWhitespace(); |
@@ -44,10 +42,9 @@ void CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange ran |
// Cycle detection. |
if (m_variablesSeen.contains(variableName)) { |
- context.success = false; |
- context.cycleStartPoints.add(variableName); |
- resolveFallback(range, trash, context); |
- return; |
+ m_cycleStartPoints.add(variableName); |
+ resolveFallback(range, trash); |
+ return false; |
} |
CSSVariableData* variableData = m_styleVariableData ? m_styleVariableData->getVariable(variableName) : nullptr; |
@@ -55,57 +52,54 @@ void CSSVariableResolver::resolveVariableTokensRecursive(CSSParserTokenRange ran |
Vector<CSSParserToken> tokens; |
if (variableData->needsVariableResolution()) { |
m_variablesSeen.add(variableName); |
- resolveVariableReferencesFromTokens(variableData->tokens(), tokens, context); |
+ bool referenceValid = resolveVariableReferencesFromTokens(variableData->tokens(), tokens); |
m_variablesSeen.remove(variableName); |
// The old variable data holds onto the backing string the new resolved CSSVariableData |
// relies on. Ensure it will live beyond us overwriting the RefPtr in StyleVariableData. |
ASSERT(variableData->refCount() > 1); |
- m_styleVariableData->setVariable(variableName, CSSVariableData::createResolved(tokens, variableData)); |
- if (!context.cycleStartPoints.isEmpty()) { |
- if (context.cycleStartPoints.contains(variableName)) |
- context.cycleStartPoints.remove(variableName); |
- |
- if (!context.cycleStartPoints.isEmpty()) { |
- resolveFallback(range, trash, context); |
- return; |
+ if (!referenceValid || !m_cycleStartPoints.isEmpty()) { |
+ m_styleVariableData->setVariable(variableName, nullptr); |
+ m_cycleStartPoints.remove(variableName); |
+ if (!m_cycleStartPoints.isEmpty()) { |
+ resolveFallback(range, trash); |
+ return false; |
} |
+ return resolveFallback(range, result); |
} |
+ |
+ m_styleVariableData->setVariable(variableName, CSSVariableData::createResolved(tokens, variableData)); |
} else { |
tokens = variableData->tokens(); |
} |
- if (!tokens.isEmpty()) { |
- // Check that loops are not induced by the fallback. |
- resolveFallback(range, trash, context); |
- if (context.cycleStartPoints.isEmpty()) { |
- // It's OK if the fallback fails to resolve - we're not actually taking it. |
- context.success = true; |
- result.appendVector(tokens); |
- } |
- return; |
+ ASSERT(!tokens.isEmpty()); |
+ // Check that loops are not induced by the fallback. |
+ resolveFallback(range, trash); |
+ if (m_cycleStartPoints.isEmpty()) { |
+ // It's OK if the fallback fails to resolve - we're not actually taking it. |
+ result.appendVector(tokens); |
+ return true; |
} |
+ return false; |
} |
- // We're legitimately falling back, so reset success flag. |
- context.success = true; |
- resolveFallback(range, result, context); |
+ return resolveFallback(range, result); |
} |
-void CSSVariableResolver::resolveVariableReferencesFromTokens(CSSParserTokenRange range, |
- Vector<CSSParserToken>& result, CSSVariableResolver::ResolutionState& context) |
+bool CSSVariableResolver::resolveVariableReferencesFromTokens(CSSParserTokenRange range, |
+ Vector<CSSParserToken>& result) |
{ |
+ bool success = true; |
while (!range.atEnd()) { |
- if (range.peek().functionId() != CSSValueVar) { |
- result.append(range.consume()); |
+ if (range.peek().functionId() == CSSValueVar) { |
+ success &= resolveVariableTokensRecursive(range.consumeBlock(), result); |
} else { |
- resolveVariableTokensRecursive(range.consumeBlock(), result, context); |
+ result.append(range.consume()); |
} |
} |
- if (!context.success) |
- result.clear(); |
- return; |
+ return success; |
} |
PassRefPtrWillBeRawPtr<CSSValue> CSSVariableResolver::resolveVariableReferences(StyleVariableData* styleVariableData, CSSPropertyID id, const CSSVariableReferenceValue& value) |
@@ -114,10 +108,7 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSVariableResolver::resolveVariableReferences( |
CSSVariableResolver resolver(styleVariableData); |
Vector<CSSParserToken> tokens; |
- ResolutionState resolutionContext; |
- resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens, resolutionContext); |
- |
- if (!resolutionContext.success) |
+ if (!resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens)) |
return cssValuePool().createUnsetValue(); |
CSSParserContext context(HTMLStandardMode, nullptr); |
@@ -136,10 +127,7 @@ void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& |
CSSVariableResolver resolver(state.style()->variables()); |
Vector<CSSParserToken> tokens; |
- ResolutionState resolutionContext; |
- resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens, resolutionContext); |
- |
- if (resolutionContext.success) { |
+ if (resolver.resolveVariableReferencesFromTokens(value.variableDataValue()->tokens(), tokens)) { |
CSSParserContext context(HTMLStandardMode, 0); |
WillBeHeapVector<CSSProperty, 256> parsedProperties; |
@@ -169,15 +157,15 @@ void CSSVariableResolver::resolveVariableDefinitions(StyleVariableData* variable |
return; |
for (auto& variable : variables->m_data) { |
- if (!variable.value->needsVariableResolution()) |
+ if (!variable.value || !variable.value->needsVariableResolution()) |
continue; |
Vector<CSSParserToken> resolvedTokens; |
CSSVariableResolver resolver(variables, variable.key); |
- ResolutionState context; |
- resolver.resolveVariableReferencesFromTokens(variable.value->tokens(), resolvedTokens, context); |
- |
- variable.value = CSSVariableData::createResolved(resolvedTokens, variable.value); |
+ if (resolver.resolveVariableReferencesFromTokens(variable.value->tokens(), resolvedTokens)) |
+ variable.value = CSSVariableData::createResolved(resolvedTokens, variable.value); |
+ else |
+ variable.value = nullptr; |
} |
} |