Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) |
| 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) | 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) |
| 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. | 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. |
| 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> | 6 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> |
| 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> | 7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) |
| 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
| 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 #include "core/rendering/style/KeyframeList.h" | 76 #include "core/rendering/style/KeyframeList.h" |
| 77 #include "core/rendering/style/StyleCustomFilterProgramCache.h" | 77 #include "core/rendering/style/StyleCustomFilterProgramCache.h" |
| 78 #include "core/svg/SVGDocumentExtensions.h" | 78 #include "core/svg/SVGDocumentExtensions.h" |
| 79 #include "core/svg/SVGElement.h" | 79 #include "core/svg/SVGElement.h" |
| 80 #include "core/svg/SVGFontFaceElement.h" | 80 #include "core/svg/SVGFontFaceElement.h" |
| 81 #include "wtf/StdLibExtras.h" | 81 #include "wtf/StdLibExtras.h" |
| 82 #include "wtf/Vector.h" | 82 #include "wtf/Vector.h" |
| 83 | 83 |
| 84 using namespace std; | 84 using namespace std; |
| 85 | 85 |
| 86 namespace { | |
| 87 | |
| 88 using namespace WebCore; | |
| 89 | |
| 90 void prepareEndKeyframes(const RenderStyle* elementStyle, const PropertySet& all Properties, KeyframeAnimationEffect::KeyframeVector& keyframes) | |
| 91 { | |
| 92 // Add 0% and 100% keyframes if absent. | |
| 93 RefPtr<Keyframe> startKeyframe = keyframes[0]; | |
| 94 if (startKeyframe->offset()) { | |
| 95 startKeyframe = Keyframe::create(); | |
| 96 startKeyframe->setOffset(0); | |
| 97 keyframes.prepend(startKeyframe); | |
| 98 } | |
| 99 RefPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1]; | |
| 100 if (endKeyframe->offset() != 1) { | |
| 101 endKeyframe = Keyframe::create(); | |
| 102 endKeyframe->setOffset(1); | |
| 103 keyframes.append(endKeyframe); | |
| 104 } | |
| 105 ASSERT(keyframes.size() >= 2); | |
| 106 ASSERT(!keyframes.first()->offset()); | |
| 107 ASSERT(keyframes.last()->offset() == 1); | |
| 108 | |
| 109 // Snapshot current property values for 0% and 100% if missing. | |
| 110 const PropertySet& startKeyframeProperties = startKeyframe->properties(); | |
| 111 const PropertySet& endKeyframeProperties = endKeyframe->properties(); | |
| 112 bool missingStartValues = startKeyframeProperties.size() < allProperties.siz e(); | |
| 113 bool missingEndValues = endKeyframeProperties.size() < allProperties.size(); | |
| 114 if (!missingStartValues && !missingEndValues) | |
| 115 return; | |
| 116 for (PropertySet::const_iterator iter = allProperties.begin(); iter != allPr operties.end(); ++iter) { | |
| 117 const CSSPropertyID property = *iter; | |
| 118 bool startNeedsValue = missingStartValues && !startKeyframeProperties.co ntains(property); | |
| 119 bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains (property); | |
| 120 if (!startNeedsValue && !endNeedsValue) | |
| 121 continue; | |
| 122 RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::creat e(property, elementStyle); | |
| 123 if (startNeedsValue) | |
| 124 startKeyframe->setPropertyValue(property, snapshotValue.get()); | |
| 125 if (endNeedsValue) | |
| 126 endKeyframe->setPropertyValue(property, snapshotValue.get()); | |
| 127 } | |
| 128 ASSERT(startKeyframe->properties().size() == allProperties.size()); | |
| 129 ASSERT(endKeyframe->properties().size() == allProperties.size()); | |
| 130 } | |
| 131 | |
| 132 PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeAnimationEffect: :KeyframeVector keyframes, const HashMap<double, RefPtr<TimingFunction> > perKey frameTimingFunctions) | |
| 133 { | |
| 134 // Generate the chained timing function. Note that timing functions apply | |
| 135 // from the keyframe in which they're specified to the next keyframe. | |
| 136 bool isTimingFunctionLinearThroughout = true; | |
| 137 RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction: :create(); | |
| 138 for (size_t i = 0; i < keyframes.size() - 1; ++i) { | |
| 139 double lowerBound = keyframes[i]->offset(); | |
| 140 ASSERT(lowerBound >=0 && lowerBound < 1); | |
| 141 double upperBound = keyframes[i + 1]->offset(); | |
| 142 ASSERT(upperBound > 0 && upperBound <= 1); | |
| 143 TimingFunction* timingFunction = perKeyframeTimingFunctions.get(lowerBou nd); | |
| 144 isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunc tion::LinearFunction; | |
| 145 chainedTimingFunction->appendSegment(upperBound, timingFunction); | |
| 146 } | |
| 147 if (isTimingFunctionLinearThroughout) | |
| 148 return LinearTimingFunction::create(); | |
| 149 return chainedTimingFunction; | |
| 150 } | |
| 151 | |
| 152 } // namespace | |
| 153 | |
| 86 namespace WebCore { | 154 namespace WebCore { |
| 87 | 155 |
| 88 using namespace HTMLNames; | 156 using namespace HTMLNames; |
| 89 | 157 |
| 90 RenderStyle* StyleResolver::s_styleNotYetAvailable; | 158 RenderStyle* StyleResolver::s_styleNotYetAvailable; |
| 91 | 159 |
| 92 static StylePropertySet* leftToRightDeclaration() | 160 static StylePropertySet* leftToRightDeclaration() |
| 93 { | 161 { |
| 94 DEFINE_STATIC_LOCAL(RefPtr<MutableStylePropertySet>, leftToRightDecl, (Mutab leStylePropertySet::create())); | 162 DEFINE_STATIC_LOCAL(RefPtr<MutableStylePropertySet>, leftToRightDecl, (Mutab leStylePropertySet::create())); |
| 95 if (leftToRightDecl->isEmpty()) | 163 if (leftToRightDecl->isEmpty()) |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 hundredPercentKeyframe = StyleKeyframe::create().leakRef(); | 894 hundredPercentKeyframe = StyleKeyframe::create().leakRef(); |
| 827 hundredPercentKeyframe->setKeyText("100%"); | 895 hundredPercentKeyframe->setKeyText("100%"); |
| 828 } | 896 } |
| 829 KeyframeValue keyframeValue(1, 0); | 897 KeyframeValue keyframeValue(1, 0); |
| 830 keyframeValue.setStyle(styleForKeyframe(e, elementStyle, hundredPercentK eyframe)); | 898 keyframeValue.setStyle(styleForKeyframe(e, elementStyle, hundredPercentK eyframe)); |
| 831 keyframeValue.addProperties(hundredPercentKeyframe->properties()); | 899 keyframeValue.addProperties(hundredPercentKeyframe->properties()); |
| 832 list.insert(keyframeValue); | 900 list.insert(keyframeValue); |
| 833 } | 901 } |
| 834 } | 902 } |
| 835 | 903 |
| 836 void StyleResolver::resolveKeyframes(const Element* element, const RenderStyle* style, const AtomicString& name, TimingFunction* defaultTimingFunction, Keyframe AnimationEffect::KeyframeVector& keyframes, RefPtr<TimingFunction>& timingFuncti on) | 904 void StyleResolver::resolveKeyframes(const Element* element, const RenderStyle* style, const AtomicString& name, TimingFunction* defaultTimingFunction, Vector<s td::pair<KeyframeAnimationEffect::KeyframeVector, RefPtr<TimingFunction> > >& ke yframesAndTimingFunctions) |
| 837 { | 905 { |
| 838 ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled()); | 906 ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled()); |
| 839 const StyleRuleKeyframes* keyframesRule = matchScopedKeyframesRule(element, name.impl()); | 907 const StyleRuleKeyframes* keyframesRule = matchScopedKeyframesRule(element, name.impl()); |
| 840 if (!keyframesRule) | 908 if (!keyframesRule) |
| 841 return; | 909 return; |
| 842 | 910 |
| 843 // Construct and populate the style for each keyframe | 911 // Construct and populate the style for each keyframe |
| 844 HashMap<double, RefPtr<TimingFunction> > timingFunctions; | 912 KeyframeAnimationEffect::KeyframeVector keyframes; |
| 913 HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions; | |
| 845 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra mes(); | 914 const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyfra mes(); |
| 846 for (size_t i = 0; i < styleKeyframes.size(); ++i) { | 915 for (size_t i = 0; i < styleKeyframes.size(); ++i) { |
| 847 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); | 916 const StyleKeyframe* styleKeyframe = styleKeyframes[i].get(); |
| 848 RefPtr<RenderStyle> keyframeStyle = styleForKeyframe(0, style, styleKeyf rame); | 917 RefPtr<RenderStyle> keyframeStyle = styleForKeyframe(0, style, styleKeyf rame); |
| 849 RefPtr<Keyframe> keyframe = Keyframe::create(); | 918 RefPtr<Keyframe> keyframe = Keyframe::create(); |
| 850 const Vector<double>& offsets = styleKeyframe->keys(); | 919 const Vector<double>& offsets = styleKeyframe->keys(); |
| 851 ASSERT(!offsets.isEmpty()); | 920 ASSERT(!offsets.isEmpty()); |
| 852 keyframe->setOffset(offsets[0]); | 921 keyframe->setOffset(offsets[0]); |
| 853 TimingFunction* timingFunction = defaultTimingFunction; | 922 TimingFunction* timingFunction = defaultTimingFunction; |
| 854 const StylePropertySet* properties = styleKeyframe->properties(); | 923 const StylePropertySet* properties = styleKeyframe->properties(); |
| 855 for (unsigned j = 0; j < properties->propertyCount(); j++) { | 924 for (unsigned j = 0; j < properties->propertyCount(); j++) { |
| 856 CSSPropertyID property = properties->propertyAt(j).id(); | 925 CSSPropertyID property = properties->propertyAt(j).id(); |
| 857 if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) { | 926 if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) { |
| 858 // FIXME: This sometimes gets the wrong timing function. See crb ug.com/288540. | 927 // FIXME: This sometimes gets the wrong timing function. See crb ug.com/288540. |
| 859 | |
| 860 timingFunction = KeyframeValue::timingFunction(keyframeStyle.get (), name); | 928 timingFunction = KeyframeValue::timingFunction(keyframeStyle.get (), name); |
| 861 } else if (CSSAnimations::isAnimatableProperty(property)) { | 929 } else if (CSSAnimations::isAnimatableProperty(property)) { |
| 862 keyframe->setPropertyValue(property, CSSAnimatableValueFactory:: create(property, keyframeStyle.get()).get()); | 930 keyframe->setPropertyValue(property, CSSAnimatableValueFactory:: create(property, keyframeStyle.get()).get()); |
| 863 } | 931 } |
| 864 } | 932 } |
| 865 keyframes.append(keyframe); | 933 keyframes.append(keyframe); |
| 866 // The last keyframe specified at a given offset is used. | 934 // The last keyframe specified at a given offset is used. |
| 867 timingFunctions.set(offsets[0], timingFunction); | 935 perKeyframeTimingFunctions.set(offsets[0], timingFunction); |
| 868 for (size_t j = 1; j < offsets.size(); ++j) { | 936 for (size_t j = 1; j < offsets.size(); ++j) { |
| 869 keyframes.append(keyframe->cloneWithOffset(offsets[j])); | 937 keyframes.append(keyframe->cloneWithOffset(offsets[j])); |
| 870 timingFunctions.set(offsets[j], timingFunction); | 938 perKeyframeTimingFunctions.set(offsets[j], timingFunction); |
| 871 } | 939 } |
| 872 } | 940 } |
| 873 | 941 |
| 874 if (keyframes.isEmpty()) | 942 if (keyframes.isEmpty()) |
| 875 return; | 943 return; |
| 876 | 944 |
| 945 if (!perKeyframeTimingFunctions.contains(0)) | |
| 946 perKeyframeTimingFunctions.set(0, defaultTimingFunction); | |
| 947 | |
| 877 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta kes priority. | 948 // Remove duplicate keyframes. In CSS the last keyframe at a given offset ta kes priority. |
| 878 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s); | 949 std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffset s); |
| 879 size_t targetIndex = 0; | 950 size_t targetIndex = 0; |
| 880 for (size_t i = 1; i < keyframes.size(); i++) { | 951 for (size_t i = 1; i < keyframes.size(); i++) { |
| 881 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) | 952 if (keyframes[i]->offset() != keyframes[targetIndex]->offset()) |
| 882 targetIndex++; | 953 targetIndex++; |
| 883 if (targetIndex != i) | 954 if (targetIndex != i) |
| 884 keyframes[targetIndex] = keyframes[i]; | 955 keyframes[targetIndex] = keyframes[i]; |
| 885 } | 956 } |
| 886 keyframes.shrink(targetIndex + 1); | 957 keyframes.shrink(targetIndex + 1); |
| 887 | 958 |
| 888 // Add 0% and 100% keyframes if absent. | 959 // Determine how many keyframes specify each property. Note that we |
| 889 RefPtr<Keyframe> startKeyframe = keyframes[0]; | 960 // consider keyframes at offsets of 0 and 1 to always specify all |
| 890 if (startKeyframe->offset()) { | 961 // properties, as values for these properties will be filled in by |
|
dstockwell
2013/09/30 07:30:57
Can't we fill in the end keyframes before counting
Steve Block
2013/09/30 12:17:54
We could, but in the case that we have to split ou
dstockwell
2013/09/30 21:56:44
It would eliminate lines 973 -> 987, right? I foun
Steve Block
2013/10/01 04:39:53
I've updated the patch to handle end keyframes fir
| |
| 891 startKeyframe = Keyframe::create(); | 962 // prepareEndKeyframes(). Note that to do this efficiently, we have to do |
| 892 startKeyframe->setOffset(0); | 963 // so after duplicate keyframes have been removed above. |
| 893 keyframes.prepend(startKeyframe); | 964 typedef HashCountedSet<CSSPropertyID> PropertyCountedSet; |
| 965 PropertyCountedSet propertyCounts; | |
| 966 size_t numKeyframes = keyframes.size(); | |
| 967 for (size_t i = 0; i < numKeyframes; ++i) { | |
| 968 const PropertySet& properties = keyframes[i]->properties(); | |
| 969 for (PropertySet::const_iterator iter = properties.begin(); iter != prop erties.end(); ++iter) | |
| 970 propertyCounts.add(*iter); | |
| 894 } | 971 } |
| 895 RefPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1]; | 972 |
| 896 if (endKeyframe->offset() != 1) { | 973 bool firstKeyframeIsAtOffsetZero = !keyframes.first()->offset(); |
| 897 endKeyframe = Keyframe::create(); | 974 bool lastKeyframeIsAtOffsetOne = keyframes.last()->offset() == 1; |
| 898 endKeyframe->setOffset(1); | 975 if (firstKeyframeIsAtOffsetZero || lastKeyframeIsAtOffsetOne) { |
| 899 keyframes.append(endKeyframe); | 976 const PropertySet& firstKeyframeProperties = keyframes.first()->properti es(); |
| 977 const PropertySet& lastKeyframeProperties = keyframes.last()->properties (); | |
| 978 if (firstKeyframeProperties.size() < propertyCounts.size() || lastKeyfra meProperties.size() < propertyCounts.size()) { | |
| 979 for (HashCountedSet<CSSPropertyID>::const_iterator iter = propertyCo unts.begin(); iter != propertyCounts.end(); ++iter) { | |
| 980 CSSPropertyID property = iter->key; | |
| 981 if (firstKeyframeIsAtOffsetZero && !keyframes.first()->propertie s().contains(property)) | |
| 982 propertyCounts.add(property); | |
| 983 if (lastKeyframeIsAtOffsetOne && !keyframes.last()->properties() .contains(property)) | |
| 984 propertyCounts.add(property); | |
| 985 } | |
| 986 } | |
| 900 } | 987 } |
| 901 ASSERT(keyframes.size() >= 2); | |
| 902 ASSERT(!keyframes.first()->offset()); | |
| 903 ASSERT(keyframes.last()->offset() == 1); | |
| 904 | 988 |
| 905 // Generate the chained timing function. Note that timing functions apply | 989 // Split keyframes into groups, where each group contains only keyframes |
| 906 // from the keyframe in which they're specified to the next keyframe. | 990 // which specify all properties used in that group. Each group is animated |
| 907 // FIXME: Handle keyframe sets where some keyframes don't specify all | 991 // in a separate animation, to allow per-keyframe timing functions to be |
| 908 // properties. In this case, timing functions apply between the keyframes | 992 // applied correctly. |
| 909 // which specify a particular property, so we'll need a separate chained | 993 PropertySet propertiesSpecifiedInAllKeyframes; |
| 910 // timing function (and therefore animation) for each property. See | 994 for (PropertyCountedSet::const_iterator iter = propertyCounts.begin(); iter != propertyCounts.end(); ++iter) { |
| 911 // LayoutTests/animations/missing-keyframe-properties-timing-function.html | 995 const CSSPropertyID property = iter->key; |
| 912 if (!timingFunctions.contains(0)) | 996 const size_t count = iter->value; |
| 913 timingFunctions.set(0, defaultTimingFunction); | 997 ASSERT(count <= numKeyframes); |
| 914 bool isTimingFunctionLinearThroughout = true; | 998 if (count == numKeyframes) { |
| 915 RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction: :create(); | 999 propertiesSpecifiedInAllKeyframes.add(property); |
| 916 for (size_t i = 0; i < keyframes.size() - 1; ++i) { | 1000 continue; |
| 917 double lowerBound = keyframes[i]->offset(); | 1001 } |
| 918 ASSERT(lowerBound >=0 && lowerBound < 1); | 1002 KeyframeAnimationEffect::KeyframeVector splitOutKeyframes; |
| 919 double upperBound = keyframes[i + 1]->offset(); | 1003 for (size_t i = 0; i < numKeyframes; i++) { |
| 920 ASSERT(upperBound > 0 && upperBound <= 1); | 1004 Keyframe* keyframe = keyframes[i].get(); |
| 921 TimingFunction* timingFunction = timingFunctions.get(lowerBound); | 1005 if (!keyframe->properties().contains(property)) |
| 922 ASSERT(timingFunction); | 1006 continue; |
| 923 isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunc tion::LinearFunction; | 1007 RefPtr<Keyframe> clonedKeyframe = Keyframe::create(); |
| 924 chainedTimingFunction->appendSegment(upperBound, timingFunction); | 1008 clonedKeyframe->setOffset(keyframe->offset()); |
| 1009 clonedKeyframe->setComposite(keyframe->composite()); | |
| 1010 clonedKeyframe->setPropertyValue(property, keyframe->propertyValue(p roperty)); | |
| 1011 splitOutKeyframes.append(clonedKeyframe); | |
| 1012 keyframe->clearPropertyValue(property); | |
| 1013 } | |
| 1014 PropertySet properties; | |
| 1015 properties.add(property); | |
| 1016 prepareEndKeyframes(style, properties, splitOutKeyframes); | |
| 1017 keyframesAndTimingFunctions.append(std::make_pair(splitOutKeyframes, gen erateTimingFunction(splitOutKeyframes, perKeyframeTimingFunctions))); | |
| 925 } | 1018 } |
| 926 if (isTimingFunctionLinearThroughout) | 1019 #ifndef NDEBUG |
| 927 timingFunction = LinearTimingFunction::create(); | 1020 size_t numPropertiesSpecifiedInAllKeyframes = propertiesSpecifiedInAllKeyfra mes.size(); |
| 928 else | 1021 for (size_t i = 0; i < keyframes.size(); ++i) |
| 929 timingFunction = chainedTimingFunction; | 1022 ASSERT(!keyframes[i]->offset() || keyframes[i]->offset() == 1 || keyfram es[i]->properties().size() == numPropertiesSpecifiedInAllKeyframes); |
| 930 | 1023 #endif |
| 931 // Snapshot current property values for 0% and 100% if missing. | 1024 prepareEndKeyframes(style, propertiesSpecifiedInAllKeyframes, keyframes); |
| 932 PropertySet allProperties; | 1025 keyframesAndTimingFunctions.append(std::make_pair(keyframes, generateTimingF unction(keyframes, perKeyframeTimingFunctions))); |
|
dstockwell
2013/09/30 07:30:57
We probably don't want to do this if numProperties
Steve Block
2013/09/30 12:17:54
Good point. Done.
| |
| 933 for (size_t i = 0; i < keyframes.size(); i++) { | |
| 934 const PropertySet& keyframeProperties = keyframes[i]->properties(); | |
| 935 for (PropertySet::const_iterator iter = keyframeProperties.begin(); iter != keyframeProperties.end(); ++iter) | |
| 936 allProperties.add(*iter); | |
| 937 } | |
| 938 const PropertySet& startKeyframeProperties = startKeyframe->properties(); | |
| 939 const PropertySet& endKeyframeProperties = endKeyframe->properties(); | |
| 940 bool missingStartValues = startKeyframeProperties.size() < allProperties.siz e(); | |
| 941 bool missingEndValues = endKeyframeProperties.size() < allProperties.size(); | |
| 942 if (!missingStartValues && !missingEndValues) | |
| 943 return; | |
| 944 for (PropertySet::const_iterator iter = allProperties.begin(); iter != allPr operties.end(); ++iter) { | |
| 945 const CSSPropertyID property = *iter; | |
| 946 bool startNeedsValue = missingStartValues && !startKeyframeProperties.co ntains(property); | |
| 947 bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains (property); | |
| 948 if (!startNeedsValue && !endNeedsValue) | |
| 949 continue; | |
| 950 RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::creat e(property, style); | |
| 951 if (startNeedsValue) | |
| 952 startKeyframe->setPropertyValue(property, snapshotValue.get()); | |
| 953 if (endNeedsValue) | |
| 954 endKeyframe->setPropertyValue(property, snapshotValue.get()); | |
| 955 } | |
| 956 ASSERT(startKeyframe->properties().size() == allProperties.size()); | |
| 957 ASSERT(endKeyframe->properties().size() == allProperties.size()); | |
| 958 } | 1026 } |
| 959 | 1027 |
| 960 PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const P seudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle) | 1028 PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* e, const P seudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle) |
| 961 { | 1029 { |
| 962 ASSERT(document().frame()); | 1030 ASSERT(document().frame()); |
| 963 ASSERT(documentSettings()); | 1031 ASSERT(documentSettings()); |
| 964 ASSERT(parentStyle); | 1032 ASSERT(parentStyle); |
| 965 if (!e) | 1033 if (!e) |
| 966 return 0; | 1034 return 0; |
| 967 | 1035 |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1605 m_matchedPropertiesSearches, m_matchedPropertiesHit, m_matchedProperties SharedInheritedHit, m_matchedPropertiesToCache, m_matchedPropertiesEnteredIntoCa che); | 1673 m_matchedPropertiesSearches, m_matchedPropertiesHit, m_matchedProperties SharedInheritedHit, m_matchedPropertiesToCache, m_matchedPropertiesEnteredIntoCa che); |
| 1606 | 1674 |
| 1607 fprintf(stderr, "Total:\n"); | 1675 fprintf(stderr, "Total:\n"); |
| 1608 printStyleStats(m_totalSearches, m_totalElementsEligibleForSharing, m_totalS tylesShared, m_totalSearchFoundSiblingForSharing, m_totalSearchesMissedSharing, | 1676 printStyleStats(m_totalSearches, m_totalElementsEligibleForSharing, m_totalS tylesShared, m_totalSearchFoundSiblingForSharing, m_totalSearchesMissedSharing, |
| 1609 m_totalMatchedPropertiesSearches, m_totalMatchedPropertiesHit, m_totalMa tchedPropertiesSharedInheritedHit, m_totalMatchedPropertiesToCache, m_totalMatch edPropertiesEnteredIntoCache); | 1677 m_totalMatchedPropertiesSearches, m_totalMatchedPropertiesHit, m_totalMa tchedPropertiesSharedInheritedHit, m_totalMatchedPropertiesToCache, m_totalMatch edPropertiesEnteredIntoCache); |
| 1610 fprintf(stderr, "----------------------------------------------------------- ---------------------\n"); | 1678 fprintf(stderr, "----------------------------------------------------------- ---------------------\n"); |
| 1611 } | 1679 } |
| 1612 #endif | 1680 #endif |
| 1613 | 1681 |
| 1614 } // namespace WebCore | 1682 } // namespace WebCore |
| OLD | NEW |