void KeyframeEffectModelBase::ensureKeyframeGroups() const
{
    if (m_keyframeGroups)
        return;

    m_keyframeGroups = adoptPtr(new KeyframeGroupMap);
    RefPtr<TimingFunction> zeroOffsetEasing = m_defaultKeyframeEasing;
    for (const auto& keyframe : normalizedKeyframes(getFrames())) {
        if (keyframe->offset() == 0)
            zeroOffsetEasing = &keyframe->easing();

        for (const PropertyHandle& property : keyframe->properties()) {
            if (property.isCSSProperty())
                ASSERT_WITH_MESSAGE(!isShorthandProperty(property.cssProperty()), "Web Animations: Encountered shorthand CSS property (%d) in normalized keyframes.", property.cssProperty());
            KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(property);
            PropertySpecificKeyframeGroup* group;
            if (groupIter == m_keyframeGroups->end())
                group = m_keyframeGroups->add(property, adoptPtr(new PropertySpecificKeyframeGroup)).storedValue->value.get();
            else
                group = groupIter->value.get();

            group->appendKeyframe(keyframe->createPropertySpecificKeyframe(property));
        }
    }

    // Add synthetic keyframes.
    m_hasSyntheticKeyframes = false;
    for (const auto& entry : *m_keyframeGroups) {
        if (entry.value->addSyntheticKeyframeIfRequired(zeroOffsetEasing))
            m_hasSyntheticKeyframes = true;

        entry.value->removeRedundantKeyframes();
    }
}
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());
}
void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
{
    ASSERT_WITH_MESSAGE(!isShorthandProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id);

    bool isInherit = state.parentNode() && value->isInheritedValue();
    bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());

    ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
    ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())

    if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
        // Limit the properties that can be applied to only the ones honored by :visited.
        return;
    }

    if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSPropertyMetadata::isInheritedProperty(id)) {
        state.parentStyle()->setHasExplicitlyInheritedProperties();
    } else if (value->isUnsetValue()) {
        ASSERT(!isInherit && !isInitial);
        if (CSSPropertyMetadata::isInheritedProperty(id))
            isInherit = true;
        else
            isInitial = true;
    }

    StyleBuilder::applyProperty(id, state, value, isInitial, isInherit);
}
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();
}
Example #5
0
String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(
    const String& propertyName) {
  CSSPropertyID propertyID = cssPropertyID(propertyName);

  // Custom properties don't have shorthands, so we can ignore them here.
  if (!propertyID || propertyID == CSSPropertyVariable)
    return String();
  if (isShorthandProperty(propertyID))
    return String();
  CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
  if (!shorthandID)
    return String();
  return getPropertyNameString(shorthandID);
}
PropertyHandleSet StringKeyframe::properties() const
{
    // This is not used in time-critical code, so we probably don't need to
    // worry about caching this result.
    PropertyHandleSet properties;
    for (unsigned i = 0; i < m_cssPropertyMap->propertyCount(); ++i) {
        StylePropertySet::PropertyReference propertyReference = m_cssPropertyMap->propertyAt(i);
        ASSERT_WITH_MESSAGE(
            !isShorthandProperty(propertyReference.id()) || propertyReference.value()->isVariableReferenceValue(),
            "Web Animations: Encountered unexpanded shorthand CSS property (%d).", propertyReference.id());
        properties.add(PropertyHandle(propertyReference.id(), false));
    }

    for (unsigned i = 0; i < m_presentationAttributeMap->propertyCount(); ++i)
        properties.add(PropertyHandle(m_presentationAttributeMap->propertyAt(i).id(), true));

    for (const auto& key: m_svgAttributeMap.keys())
        properties.add(PropertyHandle(*key));

    return properties;
}
Example #7
0
CSSInterpolationType::CSSInterpolationType(PropertyHandle property)
    : InterpolationType(property) {
  DCHECK(!isShorthandProperty(cssProperty()));
}