Example #1
0
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;
}
Example #2
0
static bool computationallyIndependent(const CSSValue& value) {
  DCHECK(!value.isCSSWideKeyword());

  if (value.isVariableReferenceValue())
    return !toCSSVariableReferenceValue(value)
                .variableDataValue()
                ->needsVariableResolution();

  if (value.isValueList()) {
    for (const CSSValue* innerValue : toCSSValueList(value)) {
      if (!computationallyIndependent(*innerValue))
        return false;
    }
    return true;
  }

  if (value.isPrimitiveValue()) {
    const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value);
    if (!primitiveValue.isLength() &&
        !primitiveValue.isCalculatedPercentageWithLength())
      return true;

    CSSPrimitiveValue::CSSLengthArray lengthArray;
    primitiveValue.accumulateLengthArray(lengthArray);
    for (size_t i = 0; i < lengthArray.values.size(); i++) {
      if (lengthArray.typeFlags.get(i) &&
          i != CSSPrimitiveValue::UnitTypePixels &&
          i != CSSPrimitiveValue::UnitTypePercentage)
        return false;
    }
    return true;
  }

  // TODO(timloh): Images and transform-function values can also contain
  // lengths.

  return true;
}