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(); }
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; }
CSSInterpolationType::CSSInterpolationType(PropertyHandle property) : InterpolationType(property) { DCHECK(!isShorthandProperty(cssProperty())); }