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

Side by Side Diff: Source/WebCore/svg/animation/SVGSMILElement.cpp

Issue 11229037: Merge 129670 - Refactor SMILTimeContainer to maintain animation information instead of recalculatin… (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1271/
Patch Set: Created 8 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
« no previous file with comments | « Source/WebCore/svg/animation/SVGSMILElement.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) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 , m_cachedRepeatCount(invalidCachedTime) 133 , m_cachedRepeatCount(invalidCachedTime)
134 , m_cachedMin(invalidCachedTime) 134 , m_cachedMin(invalidCachedTime)
135 , m_cachedMax(invalidCachedTime) 135 , m_cachedMax(invalidCachedTime)
136 { 136 {
137 resolveFirstInterval(); 137 resolveFirstInterval();
138 } 138 }
139 139
140 SVGSMILElement::~SVGSMILElement() 140 SVGSMILElement::~SVGSMILElement()
141 { 141 {
142 disconnectConditions(); 142 disconnectConditions();
143 if (m_timeContainer) 143 if (m_timeContainer && m_targetElement && hasValidAttributeName())
144 m_timeContainer->unschedule(this); 144 m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
145 if (m_targetElement) 145 if (m_targetElement)
146 document()->accessSVGExtensions()->removeAnimationElementFromTarget(this , m_targetElement); 146 document()->accessSVGExtensions()->removeAnimationElementFromTarget(this , m_targetElement);
147 } 147 }
148 148
149 static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName) 149 static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName)
150 { 150 {
151 ASSERT(svgElement); 151 ASSERT(svgElement);
152 if (attributeName.isEmpty()) 152 if (attributeName.isEmpty())
153 return anyQName(); 153 return anyQName();
154 if (!attributeName.contains(':')) 154 if (!attributeName.contains(':'))
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r ootParent) 194 Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r ootParent)
195 { 195 {
196 SVGElement::insertedInto(rootParent); 196 SVGElement::insertedInto(rootParent);
197 if (!rootParent->inDocument()) 197 if (!rootParent->inDocument())
198 return InsertionDone; 198 return InsertionDone;
199 199
200 // Verify we are not in <use> instance tree. 200 // Verify we are not in <use> instance tree.
201 ASSERT(!isInShadowTree()); 201 ASSERT(!isInShadowTree());
202 202
203 m_attributeName = constructQualifiedName(this, fastGetAttribute(SVGNames::at tributeNameAttr)); 203 setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::att ributeNameAttr)));
204 SVGSVGElement* owner = ownerSVGElement(); 204 SVGSVGElement* owner = ownerSVGElement();
205 if (!owner) 205 if (!owner)
206 return InsertionDone; 206 return InsertionDone;
207
207 m_timeContainer = owner->timeContainer(); 208 m_timeContainer = owner->timeContainer();
208 ASSERT(m_timeContainer); 209 ASSERT(m_timeContainer);
209 m_timeContainer->setDocumentOrderIndexesDirty(); 210 m_timeContainer->setDocumentOrderIndexesDirty();
210 211
211 // "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated." 212 // "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated."
212 if (!fastHasAttribute(SVGNames::beginAttr)) 213 if (!fastHasAttribute(SVGNames::beginAttr))
213 m_beginTimes.append(SMILTimeWithOrigin()); 214 m_beginTimes.append(SMILTimeWithOrigin());
214 215
215 if (m_isWaitingForFirstInterval) 216 if (m_isWaitingForFirstInterval)
216 resolveFirstInterval(); 217 resolveFirstInterval();
217 218
218 reschedule(); 219 // Force resolution of target element
220 if (!m_targetElement)
221 targetElement();
222 if (m_timeContainer)
223 m_timeContainer->notifyIntervalsChanged();
219 224
220 return InsertionDone; 225 return InsertionDone;
221 } 226 }
222 227
223 void SVGSMILElement::removedFrom(ContainerNode* rootParent) 228 void SVGSMILElement::removedFrom(ContainerNode* rootParent)
224 { 229 {
225 if (rootParent->inDocument()) { 230 if (rootParent->inDocument()) {
226 if (m_timeContainer) { 231 if (m_timeContainer) {
227 m_timeContainer->unschedule(this); 232 if (m_targetElement && hasValidAttributeName())
233 m_timeContainer->unschedule(this, m_targetElement, m_attributeNa me);
228 m_timeContainer = 0; 234 m_timeContainer = 0;
229 } 235 }
230 // Calling disconnectConditions() may kill us if there are syncbase cond itions. 236 // Calling disconnectConditions() may kill us if there are syncbase cond itions.
231 // OK, but we don't want to die inside the call. 237 // OK, but we don't want to die inside the call.
232 RefPtr<SVGSMILElement> keepAlive(this); 238 RefPtr<SVGSMILElement> keepAlive(this);
233 disconnectConditions(); 239 disconnectConditions();
234 240
235 // Clear target now, because disconnectConditions calls targetElement() which will recreate the target if we removed it sooner. 241 // Clear target now, because disconnectConditions calls targetElement() which will recreate the target if we removed it sooner.
236 if (m_targetElement) 242 if (m_targetElement)
237 resetTargetElement(); 243 resetTargetElement(DoNotResolveNewTarget);
238 244
239 m_attributeName = anyQName(); 245 setAttributeName(anyQName());
240 } 246 }
241 247
242 SVGElement::removedFrom(rootParent); 248 SVGElement::removedFrom(rootParent);
243 } 249 }
244 250
251 bool SVGSMILElement::hasValidAttributeName()
252 {
253 return attributeName() != anyQName();
254 }
255
245 SMILTime SVGSMILElement::parseOffsetValue(const String& data) 256 SMILTime SVGSMILElement::parseOffsetValue(const String& data)
246 { 257 {
247 bool ok; 258 bool ok;
248 double result = 0; 259 double result = 0;
249 String parse = data.stripWhiteSpace(); 260 String parse = data.stripWhiteSpace();
250 if (parse.endsWith('h')) 261 if (parse.endsWith('h'))
251 result = parse.left(parse.length() - 1).toDouble(&ok) * 60 * 60; 262 result = parse.left(parse.length() - 1).toDouble(&ok) * 60 * 60;
252 else if (parse.endsWith("min")) 263 else if (parse.endsWith("min"))
253 result = parse.left(parse.length() - 3).toDouble(&ok) * 60; 264 result = parse.left(parse.length() - 3).toDouble(&ok) * 60;
254 else if (parse.endsWith("ms")) 265 else if (parse.endsWith("ms"))
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 else if (attrName == SVGNames::minAttr) 469 else if (attrName == SVGNames::minAttr)
459 m_cachedMin = invalidCachedTime; 470 m_cachedMin = invalidCachedTime;
460 else if (attrName == SVGNames::maxAttr) 471 else if (attrName == SVGNames::maxAttr)
461 m_cachedMax = invalidCachedTime; 472 m_cachedMax = invalidCachedTime;
462 else if (inDocument()) { 473 else if (inDocument()) {
463 if (attrName == SVGNames::beginAttr) 474 if (attrName == SVGNames::beginAttr)
464 beginListChanged(elapsed()); 475 beginListChanged(elapsed());
465 else if (attrName == SVGNames::endAttr) 476 else if (attrName == SVGNames::endAttr)
466 endListChanged(elapsed()); 477 endListChanged(elapsed());
467 else if (attrName == SVGNames::attributeNameAttr) { 478 else if (attrName == SVGNames::attributeNameAttr) {
468 m_attributeName = constructQualifiedName(this, fastGetAttribute(SVGN ames::attributeNameAttr)); 479 setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNa mes::attributeNameAttr)));
469 if (m_targetElement) { 480 if (m_targetElement) {
470 resetTargetElement(); 481 resetTargetElement();
471 return; 482 return;
472 } 483 }
473 } else if (attrName.matches(XLinkNames::hrefAttr)) { 484 } else if (attrName.matches(XLinkNames::hrefAttr)) {
485 // targetElement is resolved lazily but targetElement() will handle calling targetElementWillChange().
474 if (SVGElement* targetElement = this->targetElement()) 486 if (SVGElement* targetElement = this->targetElement())
475 document()->accessSVGExtensions()->removeAllAnimationElementsFro mTarget(targetElement); 487 document()->accessSVGExtensions()->removeAllAnimationElementsFro mTarget(targetElement);
476 } 488 }
477 } 489 }
478 490
479 animationAttributeChanged(); 491 animationAttributeChanged();
480 } 492 }
481 493
482 inline Element* SVGSMILElement::eventBaseFor(const Condition& condition) 494 inline Element* SVGSMILElement::eventBaseFor(const Condition& condition)
483 { 495 {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 } else if (condition.m_type == Condition::Syncbase) { 548 } else if (condition.m_type == Condition::Syncbase) {
537 if (condition.m_syncbase) { 549 if (condition.m_syncbase) {
538 ASSERT(isSMILElement(condition.m_syncbase.get())); 550 ASSERT(isSMILElement(condition.m_syncbase.get()));
539 static_cast<SVGSMILElement*>(condition.m_syncbase.get())->remove TimeDependent(this); 551 static_cast<SVGSMILElement*>(condition.m_syncbase.get())->remove TimeDependent(this);
540 } 552 }
541 } 553 }
542 condition.m_syncbase = 0; 554 condition.m_syncbase = 0;
543 } 555 }
544 } 556 }
545 557
546 void SVGSMILElement::reschedule() 558 void SVGSMILElement::setAttributeName(const QualifiedName& attributeName)
547 { 559 {
548 if (m_timeContainer) 560 if (m_timeContainer && m_targetElement && m_attributeName != attributeName) {
549 m_timeContainer->schedule(this); 561 if (hasValidAttributeName())
562 m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
563 m_attributeName = attributeName;
564 if (hasValidAttributeName())
565 m_timeContainer->schedule(this, m_targetElement, m_attributeName);
566 } else
567 m_attributeName = attributeName;
550 } 568 }
551 569
552 SVGElement* SVGSMILElement::targetElement() 570 SVGElement* SVGSMILElement::targetElement()
553 { 571 {
554 if (m_targetElement) 572 if (m_targetElement)
555 return m_targetElement; 573 return m_targetElement;
556 574
557 if (!inDocument()) 575 if (!inDocument())
558 return 0; 576 return 0;
559 577
560 String href = getAttribute(XLinkNames::hrefAttr); 578 String href = getAttribute(XLinkNames::hrefAttr);
561 ContainerNode* target = href.isEmpty() ? parentNode() : SVGURIReference::tar getElementFromIRIString(href, document()); 579 ContainerNode* target = href.isEmpty() ? parentNode() : SVGURIReference::tar getElementFromIRIString(href, document());
562 if (!target || !target->isSVGElement()) 580 if (!target || !target->isSVGElement())
563 return 0; 581 return 0;
564 582
565 SVGElement* targetElement = static_cast<SVGElement*>(target); 583 SVGElement* targetElement = static_cast<SVGElement*>(target);
566 targetElementWillChange(m_targetElement, targetElement); 584 targetElementWillChange(m_targetElement, targetElement);
567 m_targetElement = targetElement; 585 m_targetElement = targetElement;
568 document()->accessSVGExtensions()->addAnimationElementToTarget(this, m_targe tElement); 586 document()->accessSVGExtensions()->addAnimationElementToTarget(this, m_targe tElement);
569 return m_targetElement; 587 return m_targetElement;
570 } 588 }
571 589
572 void SVGSMILElement::targetElementWillChange(SVGElement* currentTarget, SVGEleme nt*) 590 void SVGSMILElement::targetElementWillChange(SVGElement* currentTarget, SVGEleme nt* newTarget)
573 { 591 {
592 if (m_timeContainer && hasValidAttributeName()) {
593 if (currentTarget)
594 m_timeContainer->unschedule(this, currentTarget, m_attributeName);
595 if (newTarget)
596 m_timeContainer->schedule(this, newTarget, m_attributeName);
597 }
598
574 // Only clear the animated type, if we had a target before. 599 // Only clear the animated type, if we had a target before.
575 if (currentTarget) 600 if (currentTarget)
576 clearAnimatedType(currentTarget); 601 clearAnimatedType(currentTarget);
577 602
578 // If the animation state is not Inactive, always reset to a clear state bef ore leaving the old target element. 603 // If the animation state is not Inactive, always reset to a clear state bef ore leaving the old target element.
579 if (m_activeState != Inactive) 604 if (m_activeState != Inactive)
580 endedActiveInterval(); 605 endedActiveInterval();
581 } 606 }
582 607
583 void SVGSMILElement::resetTargetElement() 608 void SVGSMILElement::resetTargetElement(ResolveTarget resolveTarget)
584 { 609 {
585 document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_ targetElement); 610 document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_ targetElement);
586 targetElementWillChange(m_targetElement, 0); 611 targetElementWillChange(m_targetElement, 0);
587 m_targetElement = 0; 612 m_targetElement = 0;
613
614 // Immediately resolve the new targetElement (and call targetElementWillChan ge if needed) instead of doing it lazily.
615 if (resolveTarget == ResolveNewTarget)
616 targetElement();
617
588 animationAttributeChanged(); 618 animationAttributeChanged();
589 } 619 }
590 620
591 SMILTime SVGSMILElement::elapsed() const 621 SMILTime SVGSMILElement::elapsed() const
592 { 622 {
593 return m_timeContainer ? m_timeContainer->elapsed() : 0; 623 return m_timeContainer ? m_timeContainer->elapsed() : 0;
594 } 624 }
595 625
596 bool SVGSMILElement::isInactive() const 626 bool SVGSMILElement::isInactive() const
597 { 627 {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 SMILTime end; 846 SMILTime end;
817 resolveInterval(true, begin, end); 847 resolveInterval(true, begin, end);
818 ASSERT(!begin.isIndefinite()); 848 ASSERT(!begin.isIndefinite());
819 849
820 if (!begin.isUnresolved() && (begin != m_intervalBegin || end != m_intervalE nd)) { 850 if (!begin.isUnresolved() && (begin != m_intervalBegin || end != m_intervalE nd)) {
821 bool wasUnresolved = m_intervalBegin.isUnresolved(); 851 bool wasUnresolved = m_intervalBegin.isUnresolved();
822 m_intervalBegin = begin; 852 m_intervalBegin = begin;
823 m_intervalEnd = end; 853 m_intervalEnd = end;
824 notifyDependentsIntervalChanged(wasUnresolved ? NewInterval : ExistingIn terval); 854 notifyDependentsIntervalChanged(wasUnresolved ? NewInterval : ExistingIn terval);
825 m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin); 855 m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
826 reschedule(); 856
857 if (m_timeContainer)
858 m_timeContainer->notifyIntervalsChanged();
827 } 859 }
828 } 860 }
829 861
830 void SVGSMILElement::resolveNextInterval(bool notifyDependents) 862 void SVGSMILElement::resolveNextInterval(bool notifyDependents)
831 { 863 {
832 SMILTime begin; 864 SMILTime begin;
833 SMILTime end; 865 SMILTime end;
834 resolveInterval(false, begin, end); 866 resolveInterval(false, begin, end);
835 ASSERT(!begin.isIndefinite()); 867 ASSERT(!begin.isIndefinite());
836 868
(...skipping 27 matching lines...) Expand all
864 if (m_activeState == Active && m_intervalBegin > eventTime) { 896 if (m_activeState == Active && m_intervalBegin > eventTime) {
865 m_activeState = determineActiveState(eventTime); 897 m_activeState = determineActiveState(eventTime);
866 if (m_activeState != Active) 898 if (m_activeState != Active)
867 endedActiveInterval(); 899 endedActiveInterval();
868 } 900 }
869 notifyDependentsIntervalChanged(ExistingInterval); 901 notifyDependentsIntervalChanged(ExistingInterval);
870 } 902 }
871 } 903 }
872 } 904 }
873 m_nextProgressTime = elapsed(); 905 m_nextProgressTime = elapsed();
874 reschedule(); 906
907 if (m_timeContainer)
908 m_timeContainer->notifyIntervalsChanged();
875 } 909 }
876 910
877 void SVGSMILElement::endListChanged(SMILTime) 911 void SVGSMILElement::endListChanged(SMILTime)
878 { 912 {
879 SMILTime elapsed = this->elapsed(); 913 SMILTime elapsed = this->elapsed();
880 if (m_isWaitingForFirstInterval) 914 if (m_isWaitingForFirstInterval)
881 resolveFirstInterval(); 915 resolveFirstInterval();
882 else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) { 916 else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) {
883 SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false); 917 SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false);
884 if (newEnd < m_intervalEnd) { 918 if (newEnd < m_intervalEnd) {
885 newEnd = resolveActiveEnd(m_intervalBegin, newEnd); 919 newEnd = resolveActiveEnd(m_intervalBegin, newEnd);
886 if (newEnd != m_intervalEnd) { 920 if (newEnd != m_intervalEnd) {
887 m_intervalEnd = newEnd; 921 m_intervalEnd = newEnd;
888 notifyDependentsIntervalChanged(ExistingInterval); 922 notifyDependentsIntervalChanged(ExistingInterval);
889 } 923 }
890 } 924 }
891 } 925 }
892 m_nextProgressTime = elapsed; 926 m_nextProgressTime = elapsed;
893 reschedule(); 927
928 if (m_timeContainer)
929 m_timeContainer->notifyIntervalsChanged();
894 } 930 }
895 931
896 void SVGSMILElement::checkRestart(SMILTime elapsed) 932 void SVGSMILElement::checkRestart(SMILTime elapsed)
897 { 933 {
898 ASSERT(!m_isWaitingForFirstInterval); 934 ASSERT(!m_isWaitingForFirstInterval);
899 ASSERT(elapsed >= m_intervalBegin); 935 ASSERT(elapsed >= m_intervalBegin);
900 936
901 Restart restart = this->restart(); 937 Restart restart = this->restart();
902 if (restart == RestartNever) 938 if (restart == RestartNever)
903 return; 939 return;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 { 1047 {
1012 // Animation does not contribute during the active time if it is past its re peating duration and has fill=remove. 1048 // Animation does not contribute during the active time if it is past its re peating duration and has fill=remove.
1013 return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_int ervalBegin + repeatingDuration())) || m_activeState == Frozen; 1049 return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_int ervalBegin + repeatingDuration())) || m_activeState == Frozen;
1014 } 1050 }
1015 1051
1016 bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b ool seekToTime) 1052 bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b ool seekToTime)
1017 { 1053 {
1018 ASSERT(resultElement); 1054 ASSERT(resultElement);
1019 ASSERT(m_timeContainer); 1055 ASSERT(m_timeContainer);
1020 ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite()); 1056 ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
1021 1057
1022 if (!m_conditionsConnected) 1058 if (!m_conditionsConnected)
1023 connectConditions(); 1059 connectConditions();
1024 1060
1025 if (!m_intervalBegin.isFinite()) { 1061 if (!m_intervalBegin.isFinite()) {
1026 ASSERT(m_activeState == Inactive); 1062 ASSERT(m_activeState == Inactive);
1027 m_nextProgressTime = SMILTime::unresolved(); 1063 m_nextProgressTime = SMILTime::unresolved();
1028 return false; 1064 return false;
1029 } 1065 }
1030 1066
1031 if (elapsed < m_intervalBegin) { 1067 if (elapsed < m_intervalBegin) {
1032 ASSERT(m_activeState != Active); 1068 ASSERT(m_activeState != Active);
1033 if (m_activeState == Frozen) 1069 if (m_activeState == Frozen)
1034 updateAnimation(m_lastPercent, m_lastRepeat, resultElement); 1070 updateAnimation(m_lastPercent, m_lastRepeat, resultElement);
1035 m_nextProgressTime = m_intervalBegin; 1071 m_nextProgressTime = m_intervalBegin;
1036 return false; 1072 return false;
1037 } 1073 }
1038 1074
1039 m_previousIntervalBegin = m_intervalBegin; 1075 m_previousIntervalBegin = m_intervalBegin;
1040 1076
1041 if (m_isWaitingForFirstInterval) { 1077 if (m_isWaitingForFirstInterval) {
1042 m_isWaitingForFirstInterval = false; 1078 m_isWaitingForFirstInterval = false;
1043 resolveFirstInterval(); 1079 resolveFirstInterval();
1044 } 1080 }
1045 1081
1046 // This call may obtain a new interval -- never call calculateAnimationPerce ntAndRepeat() before! 1082 // This call may obtain a new interval -- never call calculateAnimationPerce ntAndRepeat() before!
1047 if (seekToTime) { 1083 if (seekToTime) {
1048 seekToIntervalCorrespondingToTime(elapsed); 1084 seekToIntervalCorrespondingToTime(elapsed);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 1189
1154 void SVGSMILElement::endedActiveInterval() 1190 void SVGSMILElement::endedActiveInterval()
1155 { 1191 {
1156 clearTimesWithDynamicOrigins(m_beginTimes); 1192 clearTimesWithDynamicOrigins(m_beginTimes);
1157 clearTimesWithDynamicOrigins(m_endTimes); 1193 clearTimesWithDynamicOrigins(m_endTimes);
1158 } 1194 }
1159 1195
1160 } 1196 }
1161 1197
1162 #endif 1198 #endif
OLDNEW
« no previous file with comments | « Source/WebCore/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698