Chromium Code Reviews| Index: Source/core/css/resolver/StyleResolver.cpp |
| diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp |
| index e1e8378cfd96c4f0aa8c644b2a7c210a9d958b60..89ca9b71f50d0e03903037391cd58184a8046235 100644 |
| --- a/Source/core/css/resolver/StyleResolver.cpp |
| +++ b/Source/core/css/resolver/StyleResolver.cpp |
| @@ -771,10 +771,9 @@ void StyleResolver::resolveKeyframes(Element* element, const RenderStyle* style, |
| // Construct and populate the style for each keyframe |
| const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes(); |
| - for (unsigned i = 0; i < styleKeyframes.size(); ++i) { |
| + for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| RefPtr<RenderStyle> keyframeStyle = styleForKeyframe(element, style, styleKeyframe); |
| - |
| Vector<float> offsets; |
| styleKeyframe->getKeys(offsets); |
| for (size_t j = 0; j < offsets.size(); ++j) { |
| @@ -784,15 +783,58 @@ void StyleResolver::resolveKeyframes(Element* element, const RenderStyle* style, |
| // FIXME: AnimatableValues should be shared between the keyframes at different offsets. |
| for (unsigned k = 0; k < properties->propertyCount(); k++) { |
| CSSPropertyID property = properties->propertyAt(k).id(); |
| - // FIXME: CSSValue needs to be resolved. |
| keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, keyframeStyle.get()).get()); |
| } |
| keyframes.append(keyframe); |
| } |
| } |
| - // FIXME: If the 0% keyframe is missing, create it (but only if there is at least one other keyframe) |
| - // FIXME: If the 100% keyframe is missing, create it (but only if there is at least one other keyframe) |
| + if (keyframes.isEmpty()) |
| + return; |
| + |
| + // Remove duplicate keyframes. In CSS the last keyframe at a given offset takes priority. |
| + std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets); |
| + size_t targetIndex = 1; |
| + for (size_t i = 1; i < keyframes.size(); i++, targetIndex++) { |
| + size_t previousIndex = targetIndex - 1; |
| + if (keyframes[i]->offset() == keyframes[previousIndex]->offset()) |
| + targetIndex = previousIndex; |
|
Steve Block
2013/08/07 01:50:45
Might be easier to read if you increment targetInd
dstockwell
2013/08/07 03:40:22
Done.
|
| + if (targetIndex != i) |
| + keyframes[targetIndex] = keyframes[i]; |
| + } |
| + keyframes.shrink(targetIndex); |
| + |
| + bool isMissingStartKeyframe = keyframes[0]->offset; |
|
Steve Block
2013/08/07 01:50:45
Yeah, the lack of '== 0' and '!= 0' is my least fa
dstockwell
2013/08/07 03:40:22
Done.
|
| + bool isMissingEndKeyframe = keyframes[keyframes.size() - 1]->offset != 1; |
| + if (!isMissingStartKeyframe && !isMissingEndKeyframe) |
| + return; |
| + |
| + HashSet<CSSPropertyID> allProperties; |
| + for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| + const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| + Vector<float> offsets; |
| + styleKeyframe->getKeys(offsets); |
| + const StylePropertySet* properties = styleKeyframe->properties(); |
| + for (unsigned j = 0; j < properties->propertyCount(); ++j) { |
| + allProperties.add(properties->propertyAt(j).id()); |
| + } |
| + } |
| + |
| + if (isMissingStartKeyframe) { |
| + RefPtr<Keyframe> keyframe = Keyframe::create(); |
| + keyframe->setOffset(0); |
| + for (HashSet<CSSPropertyID>::const_iterator iter = allProperties.begin(); iter != allProperties.end(); ++iter) |
| + keyframe->setPropertyValue(*iter, CSSAnimatableValueFactory::create(*iter, style).get()); |
| + keyframes.prepend(keyframe); |
| + } |
| + |
| + if (isMissingEndKeyframe) { |
| + RefPtr<Keyframe> keyframe = Keyframe::create(); |
| + keyframe->setOffset(1); |
| + for (HashSet<CSSPropertyID>::const_iterator iter = allProperties.begin(); iter != allProperties.end(); ++iter) |
| + keyframe->setPropertyValue(*iter, CSSAnimatableValueFactory::create(*iter, style).get()); |
| + keyframes.append(keyframe); |
| + } |
| } |
| const StylePropertySet* StyleResolver::firstKeyframeStyles(const Element* element, const StringImpl* animationName) |