• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25 
26 #ifndef SVGSMILElement_h
27 #define SVGSMILElement_h
28 
29 #include "SVGNames.h"
30 #include "core/svg/SVGElement.h"
31 #include "core/svg/animation/SMILTime.h"
32 #include "wtf/HashMap.h"
33 
34 namespace WebCore {
35 
36 class ConditionEventListener;
37 class SMILTimeContainer;
38 class SVGSMILElement;
39 
40 template<typename T> class EventSender;
41 typedef EventSender<SVGSMILElement> SMILEventSender;
42 
43 // This class implements SMIL interval timing model as needed for SVG animation.
44 class SVGSMILElement : public SVGElement {
45 public:
46     SVGSMILElement(const QualifiedName&, Document&);
47     virtual ~SVGSMILElement();
48 
49     bool isSupportedAttribute(const QualifiedName&);
50     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
51     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
52     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
53     virtual void removedFrom(ContainerNode*) OVERRIDE;
54 
55     virtual bool hasValidAttributeType() = 0;
56     virtual bool hasValidAttributeName();
57     virtual void animationAttributeChanged() = 0;
58 
timeContainer()59     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
60 
targetElement()61     SVGElement* targetElement() const { return m_targetElement; }
attributeName()62     const QualifiedName& attributeName() const { return m_attributeName; }
63 
64     void beginByLinkActivation();
65 
66     enum Restart {
67         RestartAlways,
68         RestartWhenNotActive,
69         RestartNever
70     };
71 
72     Restart restart() const;
73 
74     enum FillMode {
75         FillRemove,
76         FillFreeze
77     };
78 
79     FillMode fill() const;
80 
81     SMILTime dur() const;
82     SMILTime repeatDur() const;
83     SMILTime repeatCount() const;
84     SMILTime maxValue() const;
85     SMILTime minValue() const;
86 
87     SMILTime elapsed() const;
88 
intervalBegin()89     SMILTime intervalBegin() const { return m_intervalBegin; }
intervalEnd()90     SMILTime intervalEnd() const { return m_intervalEnd; }
previousIntervalBegin()91     SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
92     SMILTime simpleDuration() const;
93 
94     void seekToIntervalCorrespondingToTime(SMILTime elapsed);
95     bool progress(SMILTime elapsed, SVGSMILElement* resultsElement, bool seekToTime);
96     SMILTime nextProgressTime() const;
97 
98     void reset();
99 
100     static SMILTime parseClockValue(const String&);
101     static SMILTime parseOffsetValue(const String&);
102 
103     bool isContributing(SMILTime elapsed) const;
104     bool isInactive() const;
105     bool isFrozen() const;
106 
documentOrderIndex()107     unsigned documentOrderIndex() const { return m_documentOrderIndex; }
setDocumentOrderIndex(unsigned index)108     void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
109 
110     virtual bool isAdditive() const = 0;
111     virtual void resetAnimatedType() = 0;
112     virtual void clearAnimatedType(SVGElement* targetElement) = 0;
113     virtual void applyResultsToTarget() = 0;
114 
115     void connectConditions();
116 
117     void dispatchPendingEvent(SMILEventSender*);
118     void dispatchRepeatEvents(unsigned);
119 
120 protected:
121     void addBeginTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
122     void addEndTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
123 
setInactive()124     void setInactive() { m_activeState = Inactive; }
125 
126     // Sub-classes may need to take action when the target is changed.
127     virtual void setTargetElement(SVGElement*);
128     virtual void setAttributeName(const QualifiedName&);
129 
130 private:
131     void buildPendingResource();
132     void clearResourceReferences();
133 
134     virtual void startedActiveInterval() = 0;
135     void endedActiveInterval();
136     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
137 
rendererIsNeeded(const RenderStyle &)138     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
139 
140     enum BeginOrEnd {
141         Begin,
142         End
143     };
144 
145     SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
146     void resolveFirstInterval();
147     bool resolveNextInterval();
148     void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
149     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
150     SMILTime repeatingDuration() const;
151     void checkRestart(SMILTime elapsed);
152     void beginListChanged(SMILTime eventTime);
153     void endListChanged(SMILTime eventTime);
154 
155     // This represents conditions on elements begin or end list that need to be resolved on runtime
156     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
157     struct Condition {
158         enum Type {
159             EventBase,
160             Syncbase,
161             AccessKey
162         };
163 
164         Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeat = -1);
165         Type m_type;
166         BeginOrEnd m_beginOrEnd;
167         String m_baseID;
168         String m_name;
169         SMILTime m_offset;
170         int m_repeat;
171         RefPtr<Element> m_syncbase;
172         RefPtr<ConditionEventListener> m_eventListener;
173     };
174     bool parseCondition(const String&, BeginOrEnd beginOrEnd);
175     void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
176     Element* eventBaseFor(const Condition&);
177 
178     void disconnectConditions();
179 
180     // Event base timing
181     void handleConditionEvent(Event*, Condition*);
182 
183     void notifyDependentsIntervalChanged();
184     void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase);
185     void addTimeDependent(SVGSMILElement*);
186     void removeTimeDependent(SVGSMILElement*);
187 
188     enum ActiveState {
189         Inactive,
190         Active,
191         Frozen
192     };
193 
194     QualifiedName m_attributeName;
195 
196     ActiveState determineActiveState(SMILTime elapsed) const;
197     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
198     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
199 
200     mutable SVGElement* m_targetElement;
201 
202     Vector<Condition> m_conditions;
203     bool m_conditionsConnected;
204     bool m_hasEndEventConditions;
205 
206     bool m_isWaitingForFirstInterval;
207 
208     typedef HashSet<SVGSMILElement*> TimeDependentSet;
209     TimeDependentSet m_timeDependents;
210 
211     // Instance time lists
212     Vector<SMILTimeWithOrigin> m_beginTimes;
213     Vector<SMILTimeWithOrigin> m_endTimes;
214 
215     // This is the upcoming or current interval
216     SMILTime m_intervalBegin;
217     SMILTime m_intervalEnd;
218 
219     SMILTime m_previousIntervalBegin;
220 
221     ActiveState m_activeState;
222     float m_lastPercent;
223     unsigned m_lastRepeat;
224 
225     SMILTime m_nextProgressTime;
226 
227     RefPtr<SMILTimeContainer> m_timeContainer;
228     unsigned m_documentOrderIndex;
229 
230     Vector<unsigned> m_repeatEventCountList;
231 
232     mutable SMILTime m_cachedDur;
233     mutable SMILTime m_cachedRepeatDur;
234     mutable SMILTime m_cachedRepeatCount;
235     mutable SMILTime m_cachedMin;
236     mutable SMILTime m_cachedMax;
237 
238     friend class ConditionEventListener;
239 };
240 
isSVGSMILElement(const Node & node)241 inline bool isSVGSMILElement(const Node& node)
242 {
243     return node.hasTagName(SVGNames::setTag) || node.hasTagName(SVGNames::animateTag) || node.hasTagName(SVGNames::animateMotionTag)
244         || node.hasTagName(SVGNames::animateTransformTag) || node.hasTagName(SVGNames::animateColorTag);
245 }
246 
247 DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
248 
249 }
250 
251 #endif // SVGSMILElement_h
252