Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / animation / SVGSMILElement.h
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
59     SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
60
61     SVGElement* targetElement() const { return m_targetElement; }
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
89     SMILTime intervalBegin() const { return m_intervalBegin; }
90     SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
91     SMILTime simpleDuration() const;
92
93     void seekToIntervalCorrespondingToTime(SMILTime elapsed);
94     bool progress(SMILTime elapsed, SVGSMILElement* resultsElement, bool seekToTime);
95     SMILTime nextProgressTime() const;
96
97     void reset();
98
99     static SMILTime parseClockValue(const String&);
100     static SMILTime parseOffsetValue(const String&);
101
102     bool isContributing(SMILTime elapsed) const;
103     bool isFrozen() const;
104
105     unsigned documentOrderIndex() const { return m_documentOrderIndex; }
106     void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
107
108     virtual void resetAnimatedType() = 0;
109     virtual void clearAnimatedType(SVGElement* targetElement) = 0;
110     virtual void applyResultsToTarget() = 0;
111
112     void connectSyncBaseConditions();
113     void connectEventBaseConditions();
114
115     void dispatchPendingEvent(SMILEventSender*);
116     void dispatchRepeatEvents(unsigned);
117
118     virtual bool isSVGDiscardElement() const { return false; }
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
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     virtual void buildPendingResource() OVERRIDE;
132     void clearResourceAndEventBaseReferences();
133     void clearConditions();
134
135     virtual void startedActiveInterval() = 0;
136     void endedActiveInterval();
137     virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0;
138
139     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
140
141     enum BeginOrEnd {
142         Begin,
143         End
144     };
145
146     SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
147     void resolveFirstInterval();
148     bool resolveNextInterval();
149     void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
150     SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
151     SMILTime repeatingDuration() const;
152
153     enum RestartedInterval {
154         DidNotRestartInterval,
155         DidRestartInterval
156     };
157
158     RestartedInterval maybeRestartInterval(SMILTime elapsed);
159     void beginListChanged(SMILTime eventTime);
160     void endListChanged(SMILTime eventTime);
161
162     // This represents conditions on elements begin or end list that need to be resolved on runtime
163     // for example <animate begin="otherElement.begin + 8s; button.click" ... />
164     struct Condition {
165         enum Type {
166             EventBase,
167             Syncbase,
168             AccessKey
169         };
170
171         Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeat = -1);
172         Type m_type;
173         BeginOrEnd m_beginOrEnd;
174         String m_baseID;
175         String m_name;
176         SMILTime m_offset;
177         int m_repeat;
178         RefPtr<Element> m_syncbase;
179         RefPtr<ConditionEventListener> m_eventListener;
180     };
181     bool parseCondition(const String&, BeginOrEnd beginOrEnd);
182     void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
183     SVGElement* eventBaseFor(const Condition&);
184
185     void disconnectSyncBaseConditions();
186     void disconnectEventBaseConditions();
187
188     // Event base timing
189     void handleConditionEvent(Event*, Condition*);
190
191     void notifyDependentsIntervalChanged();
192     void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase);
193     void addSyncBaseDependent(SVGSMILElement*);
194     void removeSyncBaseDependent(SVGSMILElement*);
195
196     enum ActiveState {
197         Inactive,
198         Active,
199         Frozen
200     };
201
202     QualifiedName m_attributeName;
203
204     ActiveState determineActiveState(SMILTime elapsed) const;
205     float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
206     SMILTime calculateNextProgressTime(SMILTime elapsed) const;
207
208     mutable SVGElement* m_targetElement;
209
210     Vector<Condition> m_conditions;
211     bool m_syncBaseConditionsConnected;
212     bool m_hasEndEventConditions;
213
214     bool m_isWaitingForFirstInterval;
215
216     typedef HashSet<SVGSMILElement*> TimeDependentSet;
217     TimeDependentSet m_syncBaseDependents;
218
219     // Instance time lists
220     Vector<SMILTimeWithOrigin> m_beginTimes;
221     Vector<SMILTimeWithOrigin> m_endTimes;
222
223     // This is the upcoming or current interval
224     SMILTime m_intervalBegin;
225     SMILTime m_intervalEnd;
226
227     SMILTime m_previousIntervalBegin;
228
229     ActiveState m_activeState;
230     float m_lastPercent;
231     unsigned m_lastRepeat;
232
233     SMILTime m_nextProgressTime;
234
235     RefPtr<SMILTimeContainer> m_timeContainer;
236     unsigned m_documentOrderIndex;
237
238     Vector<unsigned> m_repeatEventCountList;
239
240     mutable SMILTime m_cachedDur;
241     mutable SMILTime m_cachedRepeatDur;
242     mutable SMILTime m_cachedRepeatCount;
243     mutable SMILTime m_cachedMin;
244     mutable SMILTime m_cachedMax;
245
246     friend class ConditionEventListener;
247 };
248
249 inline bool isSVGSMILElement(const Node& node)
250 {
251     return node.hasTagName(SVGNames::setTag) || node.hasTagName(SVGNames::animateTag) || node.hasTagName(SVGNames::animateMotionTag)
252         || node.hasTagName(SVGNames::animateTransformTag) || node.hasTagName((SVGNames::discardTag));
253 }
254
255 DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
256
257 }
258
259 #endif // SVGSMILElement_h