18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2008 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG_ANIMATION)
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGSMILElement.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
31e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPropertyNames.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Event.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventListener.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatConversion.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "SMILTimeContainer.h"
4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "SVGDocumentExtensions.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGNames.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGParserUtilities.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGSVGElement.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGURIReference.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "XLinkNames.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h>
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h>
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This is used for duration type time values that can't be negative.
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const double invalidCachedTime = -1.;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectclass ConditionEventListener : public EventListener {
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return adoptRef(new ConditionEventListener(animation, condition));
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    static const ConditionEventListener* cast(const EventListener* listener)
65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return listener->type() == ConditionEventListenerType
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ? static_cast<const ConditionEventListener*>(listener)
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            : 0;
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    virtual bool operator==(const EventListener& other);
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void disconnectAnimation()
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_animation = 0;
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ConditionEventListener(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        : EventListener(ConditionEventListenerType)
81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        , m_animation(animation)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , m_condition(condition)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    virtual void handleEvent(ScriptExecutionContext*, Event*);
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGSMILElement* m_animation;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGSMILElement::Condition* m_condition;
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool ConditionEventListener::operator==(const EventListener& listener)
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (const ConditionEventListener* conditionEventListener = ConditionEventListener::cast(&listener))
95cad810f21b803229eb11403f9209855525a25d57Steve Block        return m_animation == conditionEventListener->m_animation && m_condition == conditionEventListener->m_condition;
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    return false;
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid ConditionEventListener::handleEvent(ScriptExecutionContext*, Event* event)
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_animation)
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_animation->handleConditionEvent(event, m_condition);
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats)
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : m_type(type)
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_beginOrEnd(beginOrEnd)
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_baseID(baseID)
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_name(name)
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_offset(offset)
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_repeats(repeats)
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc)
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : SVGElement(tagName, doc)
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_attributeName(anyQName())
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_targetElement(0)
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_conditionsConnected(false)
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hasEndEventConditions(false)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_intervalBegin(SMILTime::unresolved())
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_intervalEnd(SMILTime::unresolved())
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_previousIntervalBegin(SMILTime::unresolved())
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_isWaitingForFirstInterval(true)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_activeState(Inactive)
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastPercent(0)
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_lastRepeat(0)
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_nextProgressTime(0)
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_documentOrderIndex(0)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_cachedDur(invalidCachedTime)
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_cachedRepeatDur(invalidCachedTime)
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_cachedRepeatCount(invalidCachedTime)
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_cachedMin(invalidCachedTime)
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_cachedMax(invalidCachedTime)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::~SVGSMILElement()
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    disconnectConditions();
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_timeContainer)
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_timeContainer->unschedule(this);
14454cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    if (m_targetElement)
14554cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement);
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
14881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochstatic inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const String& attributeName)
14981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(svgElement);
15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (attributeName.isEmpty())
15281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return anyQName();
15381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!attributeName.contains(':'))
15481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return QualifiedName(nullAtom, attributeName, nullAtom);
15581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String prefix;
15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String localName;
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ExceptionCode ec = 0;
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!Document::parseQualifiedName(attributeName, prefix, localName, ec))
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return anyQName();
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!ec);
16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String namespaceURI = svgElement->lookupNamespaceURI(prefix);
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (namespaceURI.isEmpty())
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return anyQName();
16681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return QualifiedName(nullAtom, localName, namespaceURI);
16881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::insertedIntoDocument()
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGElement::insertedIntoDocument();
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NDEBUG
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Verify we are not in <use> instance tree.
1756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    for (ContainerNode* n = this; n; n = n->parentNode())
176f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        ASSERT(!n->isShadowRoot());
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
17881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_attributeName = constructQualifiedName(this, getAttribute(SVGNames::attributeNameAttr));
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGSVGElement* owner = ownerSVGElement();
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!owner)
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_timeContainer = owner->timeContainer();
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_timeContainer);
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_timeContainer->setDocumentOrderIndexesDirty();
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reschedule();
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::removedFromDocument()
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
19081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_attributeName = anyQName();
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_timeContainer) {
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_timeContainer->unschedule(this);
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_timeContainer = 0;
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
19581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_targetElement) {
19681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        document()->accessSVGExtensions()->removeAnimationElementFromTarget(this, m_targetElement);
19781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_targetElement = 0;
19881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Calling disconnectConditions() may kill us if there are syncbase conditions.
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // OK, but we don't want to die inside the call.
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<SVGSMILElement> keepAlive(this);
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    disconnectConditions();
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGElement::removedFromDocument();
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::finishParsingChildren()
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGElement::finishParsingChildren();
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated."
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!hasAttribute(SVGNames::beginAttr))
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_beginTimes.append(0);
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isWaitingForFirstInterval) {
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resolveFirstInterval();
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reschedule();
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::parseOffsetValue(const String& data)
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ok;
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double result = 0;
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String parse = data.stripWhiteSpace();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parse.endsWith("h"))
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = parse.left(parse.length() - 1).toDouble(&ok) * 60 * 60;
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (parse.endsWith("min"))
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = parse.left(parse.length() - 3).toDouble(&ok) * 60;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (parse.endsWith("ms"))
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = parse.left(parse.length() - 2).toDouble(&ok) / 1000;
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (parse.endsWith("s"))
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = parse.left(parse.length() - 1).toDouble(&ok);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = parse.toDouble(&ok);
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ok)
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::unresolved();
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::parseClockValue(const String& data)
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (data.isNull())
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::unresolved();
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String parse = data.stripWhiteSpace();
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite"));
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parse == indefiniteValue)
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::indefinite();
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double result = 0;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ok;
253f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t doublePointOne = parse.find(':');
254f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t doublePointTwo = parse.find(':', doublePointOne + 1);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (doublePointOne == 2 && doublePointTwo == 5 && parse.length() >= 8) {
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += parse.substring(0, 2).toUIntStrict(&ok) * 60 * 60;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!ok)
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return SMILTime::unresolved();
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += parse.substring(3, 2).toUIntStrict(&ok) * 60;
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!ok)
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return SMILTime::unresolved();
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += parse.substring(6).toDouble(&ok);
263f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    } else if (doublePointOne == 2 && doublePointTwo == notFound && parse.length() >= 5) {
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += parse.substring(0, 2).toUIntStrict(&ok) * 60;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!ok)
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return SMILTime::unresolved();
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result += parse.substring(3).toDouble(&ok);
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return parseOffsetValue(parse);
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ok)
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::unresolved();
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void sortTimeList(Vector<SMILTime>& timeList)
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    std::sort(timeList.begin(), timeList.end());
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd)
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String parseString = value.stripWhiteSpace();
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double sign = 1.;
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ok;
287f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t pos = parseString.find('+');
288f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (pos == notFound) {
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos = parseString.find('-');
290f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (pos != notFound)
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            sign = -1.;
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String conditionString;
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime offset = 0;
295f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (pos == notFound)
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        conditionString = parseString;
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        conditionString = parseString.left(pos).stripWhiteSpace();
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String offsetString = parseString.substring(pos + 1).stripWhiteSpace();
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        offset = parseOffsetValue(offsetString);
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (offset.isUnresolved())
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        offset = offset * sign;
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (conditionString.isEmpty())
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pos = conditionString.find('.');
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String baseID;
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String nameString;
311f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (pos == notFound)
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nameString = conditionString;
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        baseID = conditionString.left(pos);
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nameString = conditionString.substring(pos + 1);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (nameString.isEmpty())
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Condition::Type type;
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int repeats = -1;
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (nameString.startsWith("repeat(") && nameString.endsWith(")")) {
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: For repeat events we just need to add the data carrying TimeEvent class and
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // fire the events at appropiate times.
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repeats = nameString.substring(7, nameString.length() - 8).toUIntStrict(&ok);
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!ok)
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nameString = "repeat";
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        type = Condition::EventBase;
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (nameString == "begin" || nameString == "end") {
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (baseID.isEmpty())
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        type = Condition::Syncbase;
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (nameString.startsWith("accesskey(")) {
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: accesskey() support.
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        type = Condition::AccessKey;
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        type = Condition::EventBase;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset, repeats));
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == Condition::EventBase && beginOrEnd == End)
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasEndEventConditions = true;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGSMILElement::isSMILElement(Node* node)
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!node)
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return node->hasTagName(SVGNames::setTag) || node->hasTagName(SVGNames::animateTag) || node->hasTagName(SVGNames::animateMotionTag)
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            || node->hasTagName(SVGNames::animateTransformTag) || node->hasTagName(SVGNames::animateColorTag);
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd beginOrEnd)
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<SMILTime>& timeList = beginOrEnd == Begin ? m_beginTimes : m_endTimes;
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (beginOrEnd == End)
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasEndEventConditions = false;
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HashSet<double> existing;
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < timeList.size(); ++n)
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        existing.add(timeList[n].value());
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<String> splitString;
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    parseString.split(';', splitString);
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < splitString.size(); ++n) {
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime value = parseClockValue(splitString[n]);
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (value.isUnresolved())
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parseCondition(splitString[n], beginOrEnd);
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (!existing.contains(value.value()))
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            timeList.append(value);
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sortTimeList(timeList);
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
376e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid SVGSMILElement::parseMappedAttribute(Attribute* attr)
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attr->name() == SVGNames::beginAttr) {
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_conditions.isEmpty()) {
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            disconnectConditions();
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_conditions.clear();
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parseBeginOrEnd(getAttribute(SVGNames::endAttr), End);
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parseBeginOrEnd(attr->value().string(), Begin);
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (inDocument())
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            connectConditions();
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == SVGNames::endAttr) {
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!m_conditions.isEmpty()) {
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            disconnectConditions();
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_conditions.clear();
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parseBeginOrEnd(getAttribute(SVGNames::beginAttr), Begin);
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parseBeginOrEnd(attr->value().string(), End);
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (inDocument())
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            connectConditions();
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SVGElement::parseMappedAttribute(attr);
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::attributeChanged(Attribute* attr, bool preserveDecls)
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SVGElement::attributeChanged(attr, preserveDecls);
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const QualifiedName& attrName = attr->name();
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attrName == SVGNames::durAttr)
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cachedDur = invalidCachedTime;
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attrName == SVGNames::repeatDurAttr)
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cachedRepeatDur = invalidCachedTime;
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attrName == SVGNames::repeatCountAttr)
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cachedRepeatCount = invalidCachedTime;
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attrName == SVGNames::minAttr)
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cachedMin = invalidCachedTime;
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attrName == SVGNames::maxAttr)
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_cachedMax = invalidCachedTime;
41581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else if (attrName == SVGNames::attributeNameAttr) {
41681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (inDocument())
41781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_attributeName = constructQualifiedName(this, attr->value());
41881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
41981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (inDocument()) {
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (attrName == SVGNames::beginAttr)
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beginListChanged();
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (attrName == SVGNames::endAttr)
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            endListChanged();
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockinline Element* SVGSMILElement::eventBaseFor(const Condition& condition) const
429dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
430dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return condition.m_baseID.isEmpty() ? targetElement() : document()->getElementById(condition.m_baseID);
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::connectConditions()
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_conditionsConnected)
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        disconnectConditions();
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_conditionsConnected = true;
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < m_conditions.size(); ++n) {
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Condition& condition = m_conditions[n];
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (condition.m_type == Condition::EventBase) {
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!condition.m_syncbase);
442dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            Element* eventBase = eventBaseFor(condition);
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!eventBase)
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!condition.m_eventListener);
446dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            condition.m_eventListener = ConditionEventListener::create(this, &condition);
447dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            eventBase->addEventListener(condition.m_name, condition.m_eventListener, false);
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (condition.m_type == Condition::Syncbase) {
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!condition.m_baseID.isEmpty());
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            condition.m_syncbase = document()->getElementById(condition.m_baseID);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!isSMILElement(condition.m_syncbase.get())) {
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                condition.m_syncbase = 0;
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SVGSMILElement* syncbase = static_cast<SVGSMILElement*>(condition.m_syncbase.get());
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            syncbase->addTimeDependent(this);
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::disconnectConditions()
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_conditionsConnected)
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_conditionsConnected = false;
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < m_conditions.size(); ++n) {
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Condition& condition = m_conditions[n];
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (condition.m_type == Condition::EventBase) {
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!condition.m_syncbase);
470dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (!condition.m_eventListener)
471dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                continue;
472dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // Note: It's a memory optimization to try to remove our condition
473dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // event listener, but it's not guaranteed to work, since we have
474dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // no guarantee that eventBaseFor() will be able to find our condition's
475dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // original eventBase. So, we also have to disconnect ourselves from
476dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // our condition event listener, in case it later fires.
477dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            Element* eventBase = eventBaseFor(condition);
478dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            if (eventBase)
479dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                eventBase->removeEventListener(condition.m_name, condition.m_eventListener.get(), false);
480dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            condition.m_eventListener->disconnectAnimation();
481dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            condition.m_eventListener = 0;
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (condition.m_type == Condition::Syncbase) {
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (condition.m_syncbase) {
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ASSERT(isSMILElement(condition.m_syncbase.get()));
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                static_cast<SVGSMILElement*>(condition.m_syncbase.get())->removeTimeDependent(this);
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        condition.m_syncbase = 0;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::reschedule()
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_timeContainer)
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_timeContainer->schedule(this);
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGElement* SVGSMILElement::targetElement() const
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
50081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_targetElement)
50181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return m_targetElement;
50281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String href = xlinkHref();
504a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ContainerNode* target = href.isEmpty() ? parentNode() : document()->getElementById(SVGURIReference::getTarget(href));
50581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!target || !target->isSVGElement())
50681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return 0;
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_targetElement = static_cast<SVGElement*>(target);
50981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    document()->accessSVGExtensions()->addAnimationElementToTarget(const_cast<SVGSMILElement*>(this), m_targetElement);
51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return m_targetElement;
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::elapsed() const
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_timeContainer ? m_timeContainer->elapsed() : 0;
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGSMILElement::isInactive() const
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     return m_activeState == Inactive;
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGSMILElement::isFrozen() const
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_activeState == Frozen;
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::Restart SVGSMILElement::restart() const
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
530635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, never, ("never"));
531635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, whenNotActive, ("whenNotActive"));
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::restartAttr);
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (value == never)
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return RestartNever;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (value == whenNotActive)
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return RestartWhenNotActive;
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return RestartAlways;
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::FillMode SVGSMILElement::fill() const
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
542635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, freeze, ("freeze"));
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::fillAttr);
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return value == freeze ? FillFreeze : FillRemove;
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString SVGSMILElement::xlinkHref() const
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getAttribute(XLinkNames::hrefAttr);
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::dur() const
5538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedDur != invalidCachedTime)
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_cachedDur;
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::durAttr);
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime clockValue = parseClockValue(value);
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_cachedDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue;
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::repeatDur() const
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedRepeatDur != invalidCachedTime)
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_cachedRepeatDur;
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::repeatDurAttr);
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime clockValue = parseClockValue(value);
56728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    m_cachedRepeatDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue;
56828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return m_cachedRepeatDur;
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// So a count is not really a time but let just all pretend we did not notice.
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::repeatCount() const
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedRepeatCount != invalidCachedTime)
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_cachedRepeatCount;
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::repeatCountAttr);
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (value.isNull())
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::unresolved();
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
580635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite"));
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (value == indefiniteValue)
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return SMILTime::indefinite();
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool ok;
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double result = value.string().toDouble(&ok);
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_cachedRepeatCount = ok && result > 0 ? result : SMILTime::unresolved();
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::maxValue() const
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedMax != invalidCachedTime)
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_cachedMax;
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::maxAttr);
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime result = parseClockValue(value);
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_cachedMax = (result.isUnresolved() || result < 0) ? SMILTime::indefinite() : result;
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::minValue() const
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedMin != invalidCachedTime)
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return m_cachedMin;
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& value = getAttribute(SVGNames::minAttr);
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime result = parseClockValue(value);
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_cachedMin = (result.isUnresolved() || result < 0) ? 0 : result;
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::simpleDuration() const
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return min(dur(), SMILTime::indefinite());
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::addBeginTime(SMILTime time)
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_beginTimes.append(time);
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sortTimeList(m_beginTimes);
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    beginListChanged();
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::addEndTime(SMILTime time)
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_endTimes.append(time);
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    sortTimeList(m_endTimes);
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endListChanged();
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: This searches from the beginning which is inefficient. The list is usually not long
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // (one entry in common cases) but you can construct a case where it does grow.
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const Vector<SMILTime>& list = beginOrEnd == Begin ? m_beginTimes : m_endTimes;
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < list.size(); ++n) {
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime time = list[n];
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!time.isUnresolved());
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (time.isIndefinite() && beginOrEnd == Begin) {
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // "The special value "indefinite" does not yield an instance time in the begin list."
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            continue;
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (equalsMinimumOK) {
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (time >= minimumTime)
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return time;
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (time > minimumTime)
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return time;
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return SMILTime::unresolved();
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::repeatingDuration() const
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Computing the active duration
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime repeatCount = this->repeatCount();
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime repeatDur = this->repeatDur();
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime simpleDuration = this->simpleDuration();
653cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!simpleDuration || (repeatDur.isUnresolved() && repeatCount.isUnresolved()))
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return simpleDuration;
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime repeatCountDuration = simpleDuration * repeatCount;
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return min(repeatCountDuration, min(repeatDur, SMILTime::indefinite()));
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Computing the active duration
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime preliminaryActiveDuration;
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!resolvedEnd.isUnresolved() && dur().isUnresolved() && repeatDur().isUnresolved() && repeatCount().isUnresolved())
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        preliminaryActiveDuration = resolvedEnd - resolvedBegin;
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (!resolvedEnd.isFinite())
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        preliminaryActiveDuration = repeatingDuration();
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        preliminaryActiveDuration = min(repeatingDuration(), resolvedEnd - resolvedBegin);
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime minValue = this->minValue();
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime maxValue = this->maxValue();
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (minValue > maxValue) {
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Ignore both.
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        minValue = 0;
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxValue = SMILTime::indefinite();
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return resolvedBegin + min(maxValue, max(minValue, preliminaryActiveDuration));
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See the pseudocode in
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LifeCycle
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_intervalEnd;
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity();
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (true) {
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime tempBegin = findInstanceTime(Begin, beginAfter, true);
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (tempBegin.isUnresolved())
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime tempEnd;
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_endTimes.isEmpty())
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tempEnd = resolveActiveEnd(tempBegin, SMILTime::indefinite());
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tempEnd = findInstanceTime(End, tempBegin, true);
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd) || (!first && tempEnd == m_intervalEnd))
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                tempEnd = findInstanceTime(End, tempBegin, false);
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (tempEnd.isUnresolved()) {
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!m_endTimes.isEmpty() && !m_hasEndEventConditions)
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tempEnd = resolveActiveEnd(tempBegin, tempEnd);
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (tempEnd > 0 || !first) {
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beginResult = tempBegin;
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            endResult = tempEnd;
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
709cad810f21b803229eb11403f9209855525a25d57Steve Block        }
710cad810f21b803229eb11403f9209855525a25d57Steve Block        if (restart() == RestartNever)
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
712cad810f21b803229eb11403f9209855525a25d57Steve Block
713cad810f21b803229eb11403f9209855525a25d57Steve Block        beginAfter = tempEnd;
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastIntervalTempEnd = tempEnd;
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    beginResult = SMILTime::unresolved();
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    endResult = SMILTime::unresolved();
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::resolveFirstInterval()
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime begin;
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime end;
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resolveInterval(true, begin, end);
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!begin.isIndefinite());
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!begin.isUnresolved() && (begin != m_intervalBegin || end != m_intervalEnd)) {
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool wasUnresolved = m_intervalBegin.isUnresolved();
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_intervalBegin = begin;
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_intervalEnd = end;
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        notifyDependentsIntervalChanged(wasUnresolved ? NewInterval : ExistingInterval);
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reschedule();
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::resolveNextInterval()
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime begin;
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime end;
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    resolveInterval(false, begin, end);
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!begin.isIndefinite());
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!begin.isUnresolved() && begin != m_intervalBegin) {
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_intervalBegin = begin;
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_intervalEnd = end;
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        notifyDependentsIntervalChanged(NewInterval);
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::nextProgressTime() const
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_nextProgressTime;
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::beginListChanged()
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime elapsed = this->elapsed();
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isWaitingForFirstInterval)
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resolveFirstInterval();
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (elapsed < m_intervalBegin) {
7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime newBegin = findInstanceTime(Begin, elapsed, false);
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (newBegin < m_intervalBegin) {
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Begin time changed, re-resolve the interval.
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SMILTime oldBegin = m_intervalBegin;
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_intervalBegin = elapsed;
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            resolveInterval(false, m_intervalBegin, m_intervalEnd);
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(!m_intervalBegin.isUnresolved());
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_intervalBegin != oldBegin)
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                notifyDependentsIntervalChanged(ExistingInterval);
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_nextProgressTime = elapsed;
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reschedule();
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::endListChanged()
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime elapsed = this->elapsed();
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isWaitingForFirstInterval)
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resolveFirstInterval();
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) {
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false);
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (newEnd < m_intervalEnd) {
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newEnd = resolveActiveEnd(m_intervalBegin, newEnd);
7878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (newEnd != m_intervalEnd) {
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_intervalEnd = newEnd;
7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                notifyDependentsIntervalChanged(ExistingInterval);
7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_nextProgressTime = elapsed;
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reschedule();
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::checkRestart(SMILTime elapsed)
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_isWaitingForFirstInterval);
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(elapsed >= m_intervalBegin);
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Restart restart = this->restart();
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (restart == RestartNever)
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elapsed < m_intervalEnd) {
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (restart != RestartAlways)
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false);
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (nextBegin < m_intervalEnd) {
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_intervalEnd = nextBegin;
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            notifyDependentsIntervalChanged(ExistingInterval);
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elapsed >= m_intervalEnd)
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        resolveNextInterval();
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime simpleDuration = this->simpleDuration();
8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repeat = 0;
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (simpleDuration.isIndefinite()) {
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repeat = 0;
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0.f;
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
827cad810f21b803229eb11403f9209855525a25d57Steve Block    if (!simpleDuration) {
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repeat = 0;
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1.f;
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_intervalBegin.isFinite());
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(simpleDuration.isFinite());
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime activeTime = elapsed - m_intervalBegin;
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime repeatingDuration = this->repeatingDuration();
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elapsed >= m_intervalEnd || activeTime > repeatingDuration) {
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        repeat = static_cast<unsigned>(repeatingDuration.value() / simpleDuration.value());
837cad810f21b803229eb11403f9209855525a25d57Steve Block        if (fmod(repeatingDuration.value(), !simpleDuration.value()))
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            repeat--;
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 1.f;
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    repeat = static_cast<unsigned>(activeTime.value() / simpleDuration.value());
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    SMILTime simpleTime = fmod(activeTime.value(), simpleDuration.value());
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return narrowPrecisionToFloat(simpleTime.value() / simpleDuration.value());
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_activeState == Active) {
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If duration is indefinite the value does not actually change over time. Same is true for <set>.
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SMILTime simpleDuration = this->simpleDuration();
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (simpleDuration.isIndefinite() || hasTagName(SVGNames::setTag)) {
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SMILTime repeatCount = this->repeatCount();
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SMILTime repeatingDurationEnd = m_intervalBegin + repeatingDuration();
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We are supposed to do freeze semantics when repeating ends, even if the element is still active.
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Take care that we get a timer callback at that point.
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_intervalEnd && repeatingDurationEnd.isFinite())
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return repeatingDurationEnd;
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return m_intervalEnd;
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return elapsed + 0.025;
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved();
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapsed) const
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elapsed >= m_intervalBegin && elapsed < m_intervalEnd)
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return Active;
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_activeState == Active)
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return fill() == FillFreeze ? Frozen : Inactive;
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_activeState;
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SVGSMILElement::isContributing(SMILTime elapsed) const
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Animation does not contribute during the active time if it is past its repeating duration and has fill=remove.
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_intervalBegin + repeatingDuration())) || m_activeState == Frozen;
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement)
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_timeContainer);
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_conditionsConnected)
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        connectConditions();
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_intervalBegin.isFinite()) {
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_activeState == Inactive);
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nextProgressTime = SMILTime::unresolved();
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elapsed < m_intervalBegin) {
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(m_activeState != Active);
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_activeState == Frozen && resultElement)
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            updateAnimation(m_lastPercent, m_lastRepeat, resultElement);
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_nextProgressTime = m_intervalBegin;
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_previousIntervalBegin = m_intervalBegin;
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_activeState == Inactive) {
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_isWaitingForFirstInterval = false;
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_activeState = Active;
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        startedActiveInterval();
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned repeat;
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float percent = calculateAnimationPercentAndRepeat(elapsed, repeat);
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    checkRestart(elapsed);
9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ActiveState oldActiveState = m_activeState;
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_activeState = determineActiveState(elapsed);
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isContributing(elapsed)) {
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (resultElement)
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            updateAnimation(percent, repeat, resultElement);
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastPercent = percent;
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_lastRepeat = repeat;
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (oldActiveState == Active && m_activeState != Active)
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endedActiveInterval();
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_nextProgressTime = calculateNextProgressTime(elapsed);
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::notifyDependentsIntervalChanged(NewOrExistingInterval newOrExisting)
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_intervalBegin.isFinite());
936635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(HashSet<SVGSMILElement*>, loopBreaker, ());
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (loopBreaker.contains(this))
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    loopBreaker.add(this);
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TimeDependentSet::iterator end = m_timeDependents.end();
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) {
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        SVGSMILElement* dependent = *it;
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        dependent->createInstanceTimesFromSyncbase(this, newOrExisting);
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    loopBreaker.remove(this);
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
950635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval)
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: To be really correct, this should handle updating exising interval by changing
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the associated times instead of creating new ones.
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned n = 0; n < m_conditions.size(); ++n) {
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Condition& condition = m_conditions[n];
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (condition.m_type == Condition::Syncbase && condition.m_syncbase == syncbase) {
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(condition.m_name == "begin" || condition.m_name == "end");
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // No nested time containers in SVG, no need for crazy time space conversions. Phew!
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            SMILTime time = 0;
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (condition.m_name == "begin")
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                time = syncbase->m_intervalBegin + condition.m_offset;
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                time = syncbase->m_intervalEnd + condition.m_offset;
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(time.isFinite());
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (condition.m_beginOrEnd == Begin)
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                addBeginTime(time);
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                addEndTime(time);
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::addTimeDependent(SVGSMILElement* animation)
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_timeDependents.add(animation);
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_intervalBegin.isFinite())
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        animation->createInstanceTimesFromSyncbase(this, NewInterval);
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::removeTimeDependent(SVGSMILElement* animation)
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_timeDependents.remove(animation);
9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
985635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid SVGSMILElement::handleConditionEvent(Event*, Condition* condition)
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (condition->m_beginOrEnd == Begin)
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addBeginTime(elapsed() + condition->m_offset);
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addEndTime(elapsed() + condition->m_offset);
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SVGSMILElement::beginByLinkActivation()
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    addBeginTime(elapsed());
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1001