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 #if ENABLE(SVG_ANIMATION) 29 #include "SMILTime.h" 30 #include "SVGElement.h" 31 32 #include <wtf/HashMap.h> 33 34 namespace WebCore { 35 36 class ConditionEventListener; 37 class SMILTimeContainer; 38 39 // This class implements SMIL interval timing model as needed for SVG animation. 40 class SVGSMILElement : public SVGElement { 41 public: 42 SVGSMILElement(const QualifiedName&, Document*); 43 virtual ~SVGSMILElement(); 44 45 static bool isSMILElement(Node*); 46 47 virtual void parseMappedAttribute(Attribute*); 48 virtual void attributeChanged(Attribute*, bool preserveDecls); 49 virtual void insertedIntoDocument(); 50 virtual void removedFromDocument(); 51 virtual void finishParsingChildren(); 52 53 virtual bool hasValidAttributeType() const = 0; 54 timeContainer()55 SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } 56 57 SVGElement* targetElement() const; resetTargetElement()58 void resetTargetElement() { m_targetElement = 0; } attributeName()59 const QualifiedName& attributeName() const { return m_attributeName; } 60 61 void beginByLinkActivation(); 62 63 enum Restart { 64 RestartAlways, 65 RestartWhenNotActive, 66 RestartNever 67 }; 68 69 Restart restart() const; 70 71 enum FillMode { 72 FillRemove, 73 FillFreeze 74 }; 75 76 FillMode fill() const; 77 78 String xlinkHref() const; 79 80 SMILTime dur() const; 81 SMILTime repeatDur() const; 82 SMILTime repeatCount() const; 83 SMILTime maxValue() const; 84 SMILTime minValue() const; 85 86 SMILTime elapsed() const; 87 intervalBegin()88 SMILTime intervalBegin() const { return m_intervalBegin; } intervalEnd()89 SMILTime intervalEnd() const { return m_intervalEnd; } previousIntervalBegin()90 SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; } 91 SMILTime simpleDuration() const; 92 93 void progress(SMILTime elapsed, SVGSMILElement* resultsElement); 94 SMILTime nextProgressTime() const; 95 96 static SMILTime parseClockValue(const String&); 97 static SMILTime parseOffsetValue(const String&); 98 99 bool isContributing(SMILTime elapsed) const; 100 bool isInactive() const; 101 bool isFrozen() const; 102 documentOrderIndex()103 unsigned documentOrderIndex() const { return m_documentOrderIndex; } setDocumentOrderIndex(unsigned index)104 void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; } 105 106 virtual bool isAdditive() const = 0; 107 virtual void resetToBaseValue(const String&) = 0; 108 virtual void applyResultsToTarget() = 0; 109 110 protected: 111 void addBeginTime(SMILTime); 112 void addEndTime(SMILTime); 113 114 private: 115 virtual void startedActiveInterval() = 0; 116 virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0; 117 virtual void endedActiveInterval() = 0; 118 119 enum BeginOrEnd { 120 Begin, 121 End 122 }; 123 124 SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const; 125 void resolveFirstInterval(); 126 void resolveNextInterval(); 127 void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const; 128 SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const; 129 SMILTime repeatingDuration() const; 130 void checkRestart(SMILTime elapsed); 131 void beginListChanged(); 132 void endListChanged(); 133 void reschedule(); 134 135 // This represents conditions on elements begin or end list that need to be resolved on runtime 136 // for example <animate begin="otherElement.begin + 8s; button.click" ... /> 137 struct Condition { 138 enum Type { 139 EventBase, 140 Syncbase, 141 AccessKey 142 }; 143 144 Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1); 145 Type m_type; 146 BeginOrEnd m_beginOrEnd; 147 String m_baseID; 148 String m_name; 149 SMILTime m_offset; 150 int m_repeats; 151 RefPtr<Element> m_syncbase; 152 RefPtr<ConditionEventListener> m_eventListener; 153 }; 154 bool parseCondition(const String&, BeginOrEnd beginOrEnd); 155 void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd); 156 Element* eventBaseFor(const Condition&) const; 157 158 void connectConditions(); 159 void disconnectConditions(); 160 161 // Event base timing 162 void handleConditionEvent(Event*, Condition*); 163 164 // Syncbase timing 165 enum NewOrExistingInterval { 166 NewInterval, 167 ExistingInterval 168 }; 169 170 void notifyDependentsIntervalChanged(NewOrExistingInterval); 171 void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval); 172 void addTimeDependent(SVGSMILElement*); 173 void removeTimeDependent(SVGSMILElement*); 174 175 enum ActiveState { 176 Inactive, 177 Active, 178 Frozen 179 }; 180 181 QualifiedName m_attributeName; 182 183 ActiveState determineActiveState(SMILTime elapsed) const; 184 float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const; 185 SMILTime calculateNextProgressTime(SMILTime elapsed) const; 186 187 mutable SVGElement* m_targetElement; 188 189 Vector<Condition> m_conditions; 190 bool m_conditionsConnected; 191 bool m_hasEndEventConditions; 192 193 typedef HashSet<SVGSMILElement*> TimeDependentSet; 194 TimeDependentSet m_timeDependents; 195 196 // Instance time lists 197 Vector<SMILTime> m_beginTimes; 198 Vector<SMILTime> m_endTimes; 199 200 // This is the upcoming or current interval 201 SMILTime m_intervalBegin; 202 SMILTime m_intervalEnd; 203 204 SMILTime m_previousIntervalBegin; 205 206 bool m_isWaitingForFirstInterval; 207 208 ActiveState m_activeState; 209 float m_lastPercent; 210 unsigned m_lastRepeat; 211 212 SMILTime m_nextProgressTime; 213 214 RefPtr<SMILTimeContainer> m_timeContainer; 215 unsigned m_documentOrderIndex; 216 217 mutable SMILTime m_cachedDur; 218 mutable SMILTime m_cachedRepeatDur; 219 mutable SMILTime m_cachedRepeatCount; 220 mutable SMILTime m_cachedMin; 221 mutable SMILTime m_cachedMax; 222 223 friend class ConditionEventListener; 224 }; 225 226 } 227 228 #endif // ENABLE(SVG) 229 #endif // SVGSMILElement_h 230 231