summaryrefslogtreecommitdiffstats
path: root/WebCore/svg/animation
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/svg/animation')
-rw-r--r--WebCore/svg/animation/SMILTimeContainer.cpp36
-rw-r--r--WebCore/svg/animation/SMILTimeContainer.h7
-rw-r--r--WebCore/svg/animation/SVGSMILElement.cpp35
3 files changed, 68 insertions, 10 deletions
diff --git a/WebCore/svg/animation/SMILTimeContainer.cpp b/WebCore/svg/animation/SMILTimeContainer.cpp
index a37e481..f0b479d 100644
--- a/WebCore/svg/animation/SMILTimeContainer.cpp
+++ b/WebCore/svg/animation/SMILTimeContainer.cpp
@@ -46,6 +46,7 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
: m_beginTime(0)
, m_pauseTime(0)
, m_accumulatedPauseTime(0)
+ , m_nextManualSampleTime(0)
, m_documentOrderIndexesDirty(false)
, m_timer(this, &SMILTimeContainer::timerFired)
, m_ownerSVGElement(owner)
@@ -207,14 +208,45 @@ String SMILTimeContainer::baseValueFor(ElementAttributePair key)
m_savedBaseValues.add(key, baseValue);
return baseValue;
}
-
+
+void SMILTimeContainer::sampleAnimationAtTime(const String& elementId, double newTime)
+{
+ ASSERT(m_beginTime);
+ ASSERT(!isPaused());
+
+ // Fast-forward to the time DRT wants to sample
+ m_timer.stop();
+ m_nextSamplingTarget = elementId;
+ m_nextManualSampleTime = newTime;
+
+ updateAnimations(elapsed());
+}
+
void SMILTimeContainer::updateAnimations(SMILTime elapsed)
{
SMILTime earliersFireTime = SMILTime::unresolved();
Vector<SVGSMILElement*> toAnimate;
copyToVector(m_scheduledAnimations, toAnimate);
-
+
+ if (m_nextManualSampleTime) {
+ SMILTime samplingDiff;
+ for (unsigned n = 0; n < toAnimate.size(); ++n) {
+ SVGSMILElement* animation = toAnimate[n];
+ ASSERT(animation->timeContainer() == this);
+
+ SVGElement* targetElement = animation->targetElement();
+ if (!targetElement || targetElement->getIDAttribute() != m_nextSamplingTarget)
+ continue;
+
+ samplingDiff = animation->intervalBegin();
+ break;
+ }
+
+ elapsed = SMILTime(m_nextManualSampleTime) + samplingDiff;
+ m_nextManualSampleTime = 0;
+ }
+
// Sort according to priority. Elements with later begin time have higher priority.
// In case of a tie, document order decides.
// FIXME: This should also consider timing relationships between the elements. Dependents
diff --git a/WebCore/svg/animation/SMILTimeContainer.h b/WebCore/svg/animation/SMILTimeContainer.h
index 5cef507..a6a61c0 100644
--- a/WebCore/svg/animation/SMILTimeContainer.h
+++ b/WebCore/svg/animation/SMILTimeContainer.h
@@ -60,6 +60,9 @@ namespace WebCore {
void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; }
+ // Move to a specific time. Only used for DRT testing purposes.
+ void sampleAnimationAtTime(const String& elementId, double seconds);
+
private:
SMILTimeContainer(SVGSVGElement* owner);
@@ -76,7 +79,9 @@ namespace WebCore {
double m_beginTime;
double m_pauseTime;
double m_accumulatedPauseTime;
-
+ double m_nextManualSampleTime;
+ String m_nextSamplingTarget;
+
bool m_documentOrderIndexesDirty;
Timer<SMILTimeContainer> m_timer;
diff --git a/WebCore/svg/animation/SVGSMILElement.cpp b/WebCore/svg/animation/SVGSMILElement.cpp
index 63a0d82..3957b81 100644
--- a/WebCore/svg/animation/SVGSMILElement.cpp
+++ b/WebCore/svg/animation/SVGSMILElement.cpp
@@ -61,6 +61,15 @@ public:
return adoptRef(new ConditionEventListener(animation, eventBase, condition));
}
+ static const ConditionEventListener* cast(const EventListener* listener)
+ {
+ return listener->type() == ConditionEventListenerType
+ ? static_cast<const ConditionEventListener*>(listener)
+ : 0;
+ }
+
+ virtual bool operator==(const EventListener& other);
+
void unregister()
{
// If this has only one ref then the event base is dead already and we don't need to remove ourself.
@@ -68,25 +77,37 @@ public:
m_eventBase->removeEventListener(m_condition->m_name, this, false);
}
- virtual void handleEvent(Event* event, bool)
- {
- m_animation->handleConditionEvent(event, m_condition);
- }
-
private:
ConditionEventListener(SVGSMILElement* animation, Element* eventBase, SVGSMILElement::Condition* condition)
- : m_animation(animation)
+ : EventListener(ConditionEventListenerType)
+ , m_animation(animation)
, m_condition(condition)
, m_eventBase(eventBase)
{
m_eventBase->addEventListener(m_condition->m_name, this, false);
}
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
SVGSMILElement* m_animation;
SVGSMILElement::Condition* m_condition;
Element* m_eventBase;
};
-
+
+bool ConditionEventListener::operator==(const EventListener& listener)
+{
+ if (const ConditionEventListener* conditionEventListener = ConditionEventListener::cast(&listener))
+ return m_animation == conditionEventListener->m_animation
+ && m_condition == conditionEventListener->m_condition
+ && m_eventBase == conditionEventListener->m_eventBase;
+ return false;
+}
+
+void ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+{
+ m_animation->handleConditionEvent(event, m_condition);
+}
+
SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats)
: m_type(type)
, m_beginOrEnd(beginOrEnd)