| Index: Source/core/svg/animation/SVGSMILElement.cpp
|
| diff --git a/Source/core/svg/animation/SVGSMILElement.cpp b/Source/core/svg/animation/SVGSMILElement.cpp
|
| index 37a2c122fd6e56dea8b8af9929f99220908af51a..1294aa131d43fcfa69e5a4509173b4730f6ecf42 100644
|
| --- a/Source/core/svg/animation/SVGSMILElement.cpp
|
| +++ b/Source/core/svg/animation/SVGSMILElement.cpp
|
| @@ -162,7 +162,7 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
|
| : SVGElement(tagName, doc)
|
| , m_attributeName(anyQName())
|
| , m_targetElement(0)
|
| - , m_conditionsConnected(false)
|
| + , m_syncBaseConditionsConnected(false)
|
| , m_hasEndEventConditions(false)
|
| , m_isWaitingForFirstInterval(true)
|
| , m_intervalBegin(SMILTime::unresolved())
|
| @@ -184,24 +184,25 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
|
|
|
| SVGSMILElement::~SVGSMILElement()
|
| {
|
| - clearResourceReferences();
|
| + clearResourceAndEventBaseReferences();
|
| smilEndEventSender().cancelEvent(this);
|
| smilBeginEventSender().cancelEvent(this);
|
| smilRepeatEventSender().cancelEvent(this);
|
| smilRepeatNEventSender().cancelEvent(this);
|
| - disconnectConditions();
|
| + disconnectSyncBaseConditions();
|
| + disconnectEventBaseConditions();
|
| if (m_timeContainer && m_targetElement && hasValidAttributeName())
|
| m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
|
| }
|
|
|
| -void SVGSMILElement::clearResourceReferences()
|
| +void SVGSMILElement::clearResourceAndEventBaseReferences()
|
| {
|
| document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
|
| }
|
|
|
| void SVGSMILElement::buildPendingResource()
|
| {
|
| - clearResourceReferences();
|
| + clearResourceAndEventBaseReferences();
|
|
|
| if (!inDocument()) {
|
| // Reset the target element if we are no longer in the document.
|
| @@ -238,6 +239,7 @@ void SVGSMILElement::buildPendingResource()
|
| // that leads to relayout/repainting now informs us, so we can react to it.
|
| document().accessSVGExtensions()->addElementReferencingTarget(this, svgTarget);
|
| }
|
| + connectEventBaseConditions();
|
| }
|
|
|
| static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const AtomicString& attributeName)
|
| @@ -319,8 +321,9 @@ Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r
|
| void SVGSMILElement::removedFrom(ContainerNode* rootParent)
|
| {
|
| if (rootParent->inDocument()) {
|
| - clearResourceReferences();
|
| - disconnectConditions();
|
| + clearResourceAndEventBaseReferences();
|
| + disconnectSyncBaseConditions();
|
| + disconnectEventBaseConditions();
|
| setTargetElement(0);
|
| setAttributeName(anyQName());
|
| animationAttributeChanged();
|
| @@ -502,22 +505,22 @@ void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicStrin
|
| {
|
| if (name == SVGNames::beginAttr) {
|
| if (!m_conditions.isEmpty()) {
|
| - disconnectConditions();
|
| + disconnectSyncBaseConditions();
|
| m_conditions.clear();
|
| parseBeginOrEnd(fastGetAttribute(SVGNames::endAttr), End);
|
| }
|
| parseBeginOrEnd(value.string(), Begin);
|
| if (inDocument())
|
| - connectConditions();
|
| + connectSyncBaseConditions();
|
| } else if (name == SVGNames::endAttr) {
|
| if (!m_conditions.isEmpty()) {
|
| - disconnectConditions();
|
| + disconnectSyncBaseConditions();
|
| m_conditions.clear();
|
| parseBeginOrEnd(fastGetAttribute(SVGNames::beginAttr), Begin);
|
| }
|
| parseBeginOrEnd(value.string(), End);
|
| if (inDocument())
|
| - connectConditions();
|
| + connectSyncBaseConditions();
|
| } else if (name == SVGNames::onbeginAttr) {
|
| setAttributeEventListener(EventTypeNames::beginEvent, createAttributeEventListener(this, name, value));
|
| } else if (name == SVGNames::onendAttr) {
|
| @@ -567,38 +570,63 @@ inline Element* SVGSMILElement::eventBaseFor(const Condition& condition)
|
| return condition.m_baseID.isEmpty() ? targetElement() : treeScope().getElementById(AtomicString(condition.m_baseID));
|
| }
|
|
|
| -void SVGSMILElement::connectConditions()
|
| +void SVGSMILElement::connectSyncBaseConditions()
|
| {
|
| - if (m_conditionsConnected)
|
| - disconnectConditions();
|
| - m_conditionsConnected = true;
|
| + if (m_syncBaseConditionsConnected)
|
| + disconnectSyncBaseConditions();
|
| + m_syncBaseConditionsConnected = true;
|
| for (unsigned n = 0; n < m_conditions.size(); ++n) {
|
| Condition& condition = m_conditions[n];
|
| - if (condition.m_type == Condition::EventBase) {
|
| - ASSERT(!condition.m_syncbase);
|
| - Element* eventBase = eventBaseFor(condition);
|
| - if (!eventBase)
|
| - continue;
|
| - ASSERT(!condition.m_eventListener);
|
| - condition.m_eventListener = ConditionEventListener::create(this, &condition);
|
| - eventBase->addEventListener(AtomicString(condition.m_name), condition.m_eventListener, false);
|
| - } else if (condition.m_type == Condition::Syncbase) {
|
| + if (condition.m_type == Condition::Syncbase) {
|
| ASSERT(!condition.m_baseID.isEmpty());
|
| condition.m_syncbase = treeScope().getElementById(AtomicString(condition.m_baseID));
|
| if (!condition.m_syncbase || !isSVGSMILElement(*condition.m_syncbase)) {
|
| condition.m_syncbase = 0;
|
| continue;
|
| }
|
| - toSVGSMILElement(condition.m_syncbase.get())->addTimeDependent(this);
|
| + toSVGSMILElement(condition.m_syncbase.get())->addSyncBaseDependent(this);
|
| }
|
| }
|
| }
|
|
|
| -void SVGSMILElement::disconnectConditions()
|
| +void SVGSMILElement::disconnectSyncBaseConditions()
|
| {
|
| - if (!m_conditionsConnected)
|
| + if (!m_syncBaseConditionsConnected)
|
| return;
|
| - m_conditionsConnected = false;
|
| + m_syncBaseConditionsConnected = false;
|
| + for (unsigned n = 0; n < m_conditions.size(); ++n) {
|
| + Condition& condition = m_conditions[n];
|
| + if (condition.m_type == Condition::Syncbase) {
|
| + if (condition.m_syncbase)
|
| + toSVGSMILElement(condition.m_syncbase.get())->removeSyncBaseDependent(this);
|
| + condition.m_syncbase = 0;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void SVGSMILElement::connectEventBaseConditions()
|
| +{
|
| + disconnectEventBaseConditions();
|
| + for (unsigned n = 0; n < m_conditions.size(); ++n) {
|
| + Condition& condition = m_conditions[n];
|
| + if (condition.m_type == Condition::EventBase) {
|
| + ASSERT(!condition.m_syncbase);
|
| + Element* eventBase = eventBaseFor(condition);
|
| + if (!eventBase) {
|
| + if (!condition.m_baseID.isEmpty() && !document().accessSVGExtensions()->isElementPendingResource(this, AtomicString(condition.m_baseID)))
|
| + document().accessSVGExtensions()->addPendingResource(AtomicString(condition.m_baseID), this);
|
| + continue;
|
| + }
|
| + ASSERT(!condition.m_eventListener);
|
| + condition.m_eventListener = ConditionEventListener::create(this, &condition);
|
| + eventBase->addEventListener(AtomicString(condition.m_name), condition.m_eventListener, false);
|
| + document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(eventBase));
|
| + }
|
| + }
|
| +}
|
| +
|
| +void SVGSMILElement::disconnectEventBaseConditions()
|
| +{
|
| for (unsigned n = 0; n < m_conditions.size(); ++n) {
|
| Condition& condition = m_conditions[n];
|
| if (condition.m_type == Condition::EventBase) {
|
| @@ -615,11 +643,7 @@ void SVGSMILElement::disconnectConditions()
|
| eventBase->removeEventListener(AtomicString(condition.m_name), condition.m_eventListener.get(), false);
|
| condition.m_eventListener->disconnectAnimation();
|
| condition.m_eventListener = 0;
|
| - } else if (condition.m_type == Condition::Syncbase) {
|
| - if (condition.m_syncbase)
|
| - toSVGSMILElement(condition.m_syncbase.get())->removeTimeDependent(this);
|
| }
|
| - condition.m_syncbase = 0;
|
| }
|
| }
|
|
|
| @@ -651,7 +675,7 @@ void SVGSMILElement::setTargetElement(SVGElement* target)
|
| if (m_targetElement) {
|
| // Clear values that may depend on the previous target.
|
| clearAnimatedType(m_targetElement);
|
| - disconnectConditions();
|
| + disconnectSyncBaseConditions();
|
| }
|
|
|
| // If the animation state is not Inactive, always reset to a clear state before leaving the old target element.
|
| @@ -1098,8 +1122,8 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
|
| ASSERT(m_timeContainer);
|
| ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
|
|
|
| - if (!m_conditionsConnected)
|
| - connectConditions();
|
| + if (!m_syncBaseConditionsConnected)
|
| + connectSyncBaseConditions();
|
|
|
| if (!m_intervalBegin.isFinite()) {
|
| ASSERT(m_activeState == Inactive);
|
| @@ -1195,8 +1219,8 @@ void SVGSMILElement::notifyDependentsIntervalChanged()
|
| if (!loopBreaker.add(this).isNewEntry)
|
| return;
|
|
|
| - TimeDependentSet::iterator end = m_timeDependents.end();
|
| - for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) {
|
| + TimeDependentSet::iterator end = m_syncBaseDependents.end();
|
| + for (TimeDependentSet::iterator it = m_syncBaseDependents.begin(); it != end; ++it) {
|
| SVGSMILElement* dependent = *it;
|
| dependent->createInstanceTimesFromSyncbase(this);
|
| }
|
| @@ -1227,16 +1251,16 @@ void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase)
|
| }
|
| }
|
|
|
| -void SVGSMILElement::addTimeDependent(SVGSMILElement* animation)
|
| +void SVGSMILElement::addSyncBaseDependent(SVGSMILElement* animation)
|
| {
|
| - m_timeDependents.add(animation);
|
| + m_syncBaseDependents.add(animation);
|
| if (m_intervalBegin.isFinite())
|
| animation->createInstanceTimesFromSyncbase(this);
|
| }
|
|
|
| -void SVGSMILElement::removeTimeDependent(SVGSMILElement* animation)
|
| +void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement* animation)
|
| {
|
| - m_timeDependents.remove(animation);
|
| + m_syncBaseDependents.remove(animation);
|
| }
|
|
|
| void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition)
|
|
|