Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: Source/core/css/resolver/StyleResolver.cpp

Issue 23875044: Web Animations: Correctly handle incomplete keyframes in CSS animations (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebased Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/css/resolver/StyleResolver.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/css/resolver/StyleResolver.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698