2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef SVGSMILElement_h
27 #define SVGSMILElement_h
30 #include "SVGElement.h"
32 #include <wtf/HashMap.h>
36 class ConditionEventListener;
37 class SMILTimeContainer;
39 // This class implements SMIL interval timing model as needed for SVG animation.
40 class SVGSMILElement : public SVGElement {
42 SVGSMILElement(const QualifiedName&, Document*);
43 virtual ~SVGSMILElement();
45 static bool isSMILElement(Node*);
47 bool isSupportedAttribute(const QualifiedName&);
48 virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
49 virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
50 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
51 virtual void removedFrom(ContainerNode*) OVERRIDE;
53 virtual bool hasValidAttributeType() = 0;
54 virtual bool hasValidAttributeName();
55 virtual void animationAttributeChanged() = 0;
57 SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
59 SVGElement* targetElement() const { return m_targetElement; }
60 const QualifiedName& attributeName() const { return m_attributeName; }
62 void beginByLinkActivation();
70 Restart restart() const;
77 FillMode fill() const;
80 SMILTime repeatDur() const;
81 SMILTime repeatCount() const;
82 SMILTime maxValue() const;
83 SMILTime minValue() const;
85 SMILTime elapsed() const;
87 SMILTime intervalBegin() const { return m_intervalBegin; }
88 SMILTime intervalEnd() const { return m_intervalEnd; }
89 SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
90 SMILTime simpleDuration() const;
92 void seekToIntervalCorrespondingToTime(SMILTime elapsed);
93 bool progress(SMILTime elapsed, SVGSMILElement* resultsElement, bool seekToTime);
94 SMILTime nextProgressTime() const;
98 static SMILTime parseClockValue(const String&);
99 static SMILTime parseOffsetValue(const String&);
101 bool isContributing(SMILTime elapsed) const;
102 bool isInactive() const;
103 bool isFrozen() const;
105 unsigned documentOrderIndex() const { return m_documentOrderIndex; }
106 void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
108 virtual bool isAdditive() const = 0;
109 virtual void resetAnimatedType() = 0;
110 virtual void clearAnimatedType(SVGElement* targetElement) = 0;
111 virtual void applyResultsToTarget() = 0;
114 void addBeginTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
115 void addEndTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
117 void setInactive() { m_activeState = Inactive; }
119 // Sub-classes may need to take action when the target is changed.
120 virtual void setTargetElement(SVGElement*);
121 virtual void setAttributeName(const QualifiedName&);
124 void buildPendingResource();
125 void clearResourceReferences();
127 virtual void startedActiveInterval() = 0;
128 void endedActiveInterval();
129 virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
136 SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
137 void resolveFirstInterval();
138 void resolveNextInterval(bool notifyDependents);
139 void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
140 SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
141 SMILTime repeatingDuration() const;
142 void checkRestart(SMILTime elapsed);
143 void beginListChanged(SMILTime eventTime);
144 void endListChanged(SMILTime eventTime);
146 // This represents conditions on elements begin or end list that need to be resolved on runtime
147 // for example <animate begin="otherElement.begin + 8s; button.click" ... />
155 Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1);
157 BeginOrEnd m_beginOrEnd;
162 RefPtr<Element> m_syncbase;
163 RefPtr<ConditionEventListener> m_eventListener;
165 bool parseCondition(const String&, BeginOrEnd beginOrEnd);
166 void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
167 Element* eventBaseFor(const Condition&);
169 void connectConditions();
170 void disconnectConditions();
173 void handleConditionEvent(Event*, Condition*);
176 enum NewOrExistingInterval {
181 void notifyDependentsIntervalChanged(NewOrExistingInterval);
182 void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval);
183 void addTimeDependent(SVGSMILElement*);
184 void removeTimeDependent(SVGSMILElement*);
192 QualifiedName m_attributeName;
194 ActiveState determineActiveState(SMILTime elapsed) const;
195 float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
196 SMILTime calculateNextProgressTime(SMILTime elapsed) const;
198 mutable SVGElement* m_targetElement;
200 Vector<Condition> m_conditions;
201 bool m_conditionsConnected;
202 bool m_hasEndEventConditions;
204 bool m_isWaitingForFirstInterval;
206 typedef HashSet<SVGSMILElement*> TimeDependentSet;
207 TimeDependentSet m_timeDependents;
209 // Instance time lists
210 Vector<SMILTimeWithOrigin> m_beginTimes;
211 Vector<SMILTimeWithOrigin> m_endTimes;
213 // This is the upcoming or current interval
214 SMILTime m_intervalBegin;
215 SMILTime m_intervalEnd;
217 SMILTime m_previousIntervalBegin;
219 ActiveState m_activeState;
221 unsigned m_lastRepeat;
223 SMILTime m_nextProgressTime;
225 RefPtr<SMILTimeContainer> m_timeContainer;
226 unsigned m_documentOrderIndex;
228 mutable SMILTime m_cachedDur;
229 mutable SMILTime m_cachedRepeatDur;
230 mutable SMILTime m_cachedRepeatCount;
231 mutable SMILTime m_cachedMin;
232 mutable SMILTime m_cachedMax;
234 friend class ConditionEventListener;
239 #endif // ENABLE(SVG)
240 #endif // SVGSMILElement_h