void CSSVariableResolver::resolveAndApplyVariableReferences(StyleResolverState& state, CSSPropertyID id, const CSSVariableReferenceValue& value) { CSSVariableResolver resolver(state.style()->variables()); Vector<CSSParserToken> tokens; if (resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) { CSSParserContext context(HTMLStandardMode, 0); HeapVector<CSSProperty, 256> parsedProperties; // TODO: Non-shorthands should just call CSSPropertyParser::parseSingleValue if (CSSPropertyParser::parseValue(id, false, CSSParserTokenRange(tokens), context, parsedProperties, StyleRule::RuleType::Style)) { unsigned parsedPropertiesCount = parsedProperties.size(); for (unsigned i = 0; i < parsedPropertiesCount; ++i) StyleBuilder::applyProperty(parsedProperties[i].id(), state, parsedProperties[i].value()); return; } } RawPtr<CSSUnsetValue> unset = cssValuePool().createUnsetValue(); if (isShorthandProperty(id)) { StylePropertyShorthand shorthand = shorthandForProperty(id); for (unsigned i = 0; i < shorthand.length(); i++) StyleBuilder::applyProperty(shorthand.properties()[i], state, unset.get()); return; } StyleBuilder::applyProperty(id, state, unset.get()); }
RawPtr<CSSValue> CSSVariableResolver::resolveVariableReferences(StyleVariableData* styleVariableData, CSSPropertyID id, const CSSVariableReferenceValue& value) { ASSERT(!isShorthandProperty(id)); CSSVariableResolver resolver(styleVariableData); Vector<CSSParserToken> tokens; if (!resolver.resolveTokenRange(value.variableDataValue()->tokens(), tokens)) return cssValuePool().createUnsetValue(); RawPtr<CSSValue> result = CSSPropertyParser::parseSingleValue(id, tokens, strictCSSParserContext()); if (!result) return cssValuePool().createUnsetValue(); return result.release(); }
RefPtr<CSSValue> CSSParser::parseValueWithVariableReferences(CSSPropertyID propID, const CSSValue& value, const CustomPropertyValueMap& customProperties, TextDirection direction, WritingMode writingMode) { if (value.isPendingSubstitutionValue()) { // FIXME: Should have a resolvedShorthands cache to stop this from being done // over and over for each longhand value. const CSSPendingSubstitutionValue& pendingSubstitution = downcast<CSSPendingSubstitutionValue>(value); CSSPropertyID shorthandID = pendingSubstitution.shorthandPropertyId(); if (CSSProperty::isDirectionAwareProperty(shorthandID)) shorthandID = CSSProperty::resolveDirectionAwareProperty(shorthandID, direction, writingMode); CSSVariableReferenceValue* shorthandValue = pendingSubstitution.shorthandValue(); const CSSVariableData* variableData = shorthandValue->variableDataValue(); ASSERT(variableData); Vector<CSSParserToken> resolvedTokens; if (!variableData->resolveTokenRange(customProperties, variableData->tokens(), resolvedTokens)) return nullptr; ParsedPropertyVector parsedProperties; if (!CSSPropertyParser::parseValue(shorthandID, false, resolvedTokens, m_context, nullptr, parsedProperties, StyleRule::Style)) return nullptr; for (auto& property : parsedProperties) { if (property.id() == propID) return property.value(); } return nullptr; } if (value.isVariableReferenceValue()) { const CSSVariableReferenceValue& valueWithReferences = downcast<CSSVariableReferenceValue>(value); const CSSVariableData* variableData = valueWithReferences.variableDataValue(); ASSERT(variableData); Vector<CSSParserToken> resolvedTokens; if (!variableData->resolveTokenRange(customProperties, variableData->tokens(), resolvedTokens)) return nullptr; return CSSPropertyParser::parseSingleValue(propID, resolvedTokens, m_context, nullptr); } return nullptr; }