Index: third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp |
diff --git a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp |
index b7f10aac622757aedc738a1d2b7be8b5fc591a38..762155ecd6edcdddc34c3be6a1d67fdbe11ed7e3 100644 |
--- a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp |
+++ b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp |
@@ -124,15 +124,10 @@ void ConditionEventListener::handleEvent(ExecutionContext*, Event* event) { |
m_animation->handleConditionEvent(event, m_condition); |
} |
-void SVGSMILElement::Condition::setEventListener( |
- ConditionEventListener* eventListener) { |
- m_eventListener = eventListener; |
-} |
- |
SVGSMILElement::Condition::Condition(Type type, |
BeginOrEnd beginOrEnd, |
- const String& baseID, |
- const String& name, |
+ const AtomicString& baseID, |
+ const AtomicString& name, |
SMILTime offset, |
int repeat) |
: m_type(type), |
@@ -142,6 +137,76 @@ SVGSMILElement::Condition::Condition(Type type, |
m_offset(offset), |
m_repeat(repeat) {} |
+SVGSMILElement::Condition::~Condition() = default; |
+ |
+DEFINE_TRACE(SVGSMILElement::Condition) { |
+ visitor->trace(m_syncBase); |
+ visitor->trace(m_eventListener); |
+} |
+ |
+void SVGSMILElement::Condition::connectSyncBase(SVGSMILElement& timedElement) { |
+ DCHECK(!m_baseID.isEmpty()); |
+ Element* element = timedElement.treeScope().getElementById(m_baseID); |
+ if (!element || !isSVGSMILElement(*element)) { |
+ m_syncBase = nullptr; |
+ return; |
+ } |
+ m_syncBase = toSVGSMILElement(element); |
+ m_syncBase->addSyncBaseDependent(timedElement); |
+} |
+ |
+void SVGSMILElement::Condition::disconnectSyncBase( |
+ SVGSMILElement& timedElement) { |
+ if (!m_syncBase) |
+ return; |
+ m_syncBase->removeSyncBaseDependent(timedElement); |
+ m_syncBase = nullptr; |
+} |
+ |
+SVGElement* SVGSMILElement::Condition::lookupEventBase( |
+ SVGSMILElement& timedElement) const { |
+ Element* eventBase = m_baseID.isEmpty() |
+ ? timedElement.targetElement() |
+ : timedElement.treeScope().getElementById(m_baseID); |
+ if (!eventBase || !eventBase->isSVGElement()) |
+ return nullptr; |
+ return toSVGElement(eventBase); |
+} |
+ |
+void SVGSMILElement::Condition::connectEventBase(SVGSMILElement& timedElement) { |
+ DCHECK(!m_syncBase); |
+ SVGElement* eventBase = lookupEventBase(timedElement); |
+ if (!eventBase) { |
+ if (m_baseID.isEmpty()) |
+ return; |
+ SVGTreeScopeResources& treeScopeResources = |
+ timedElement.treeScope().ensureSVGTreeScopedResources(); |
+ if (!treeScopeResources.isElementPendingResource(timedElement, m_baseID)) |
+ treeScopeResources.addPendingResource(m_baseID, timedElement); |
+ return; |
+ } |
+ DCHECK(!m_eventListener); |
+ m_eventListener = ConditionEventListener::create(&timedElement, this); |
+ eventBase->addEventListener(m_name, m_eventListener, false); |
+ timedElement.addReferenceTo(eventBase); |
+} |
+ |
+void SVGSMILElement::Condition::disconnectEventBase( |
+ SVGSMILElement& timedElement) { |
+ DCHECK(!m_syncBase); |
+ if (!m_eventListener) |
+ return; |
+ // Note: It's a memory optimization to try to remove our condition event |
+ // listener, but it's not guaranteed to work, since we have no guarantee that |
+ // we will be able to find our condition's original eventBase. So, we also |
+ // have to disconnect ourselves from our condition event listener, in case it |
+ // later fires. |
+ if (SVGElement* eventBase = lookupEventBase(timedElement)) |
+ eventBase->removeEventListener(m_name, m_eventListener, false); |
+ m_eventListener->disconnectAnimation(); |
+ m_eventListener = nullptr; |
+} |
+ |
SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc) |
: SVGElement(tagName, doc), |
SVGTests(this), |
@@ -413,7 +478,8 @@ bool SVGSMILElement::parseCondition(const String& value, |
} |
m_conditions.push_back( |
- Condition::create(type, beginOrEnd, baseID, nameString, offset, repeat)); |
+ Condition::create(type, beginOrEnd, AtomicString(baseID), |
+ AtomicString(nameString), offset, repeat)); |
if (type == Condition::EventBase && beginOrEnd == End) |
m_hasEndEventConditions = true; |
@@ -516,34 +582,13 @@ void SVGSMILElement::svgAttributeChanged(const QualifiedName& attrName) { |
animationAttributeChanged(); |
} |
-inline SVGElement* SVGSMILElement::eventBaseFor(const Condition& condition) { |
- Element* eventBase = |
- condition.baseID().isEmpty() |
- ? targetElement() |
- : treeScope().getElementById(AtomicString(condition.baseID())); |
- if (eventBase && eventBase->isSVGElement()) |
- return toSVGElement(eventBase); |
- return nullptr; |
-} |
- |
void SVGSMILElement::connectSyncBaseConditions() { |
if (m_syncBaseConditionsConnected) |
disconnectSyncBaseConditions(); |
m_syncBaseConditionsConnected = true; |
- for (unsigned n = 0; n < m_conditions.size(); ++n) { |
- Condition* condition = m_conditions[n].get(); |
- if (condition->getType() == Condition::Syncbase) { |
- ASSERT(!condition->baseID().isEmpty()); |
- Element* element = |
- treeScope().getElementById(AtomicString(condition->baseID())); |
- if (!element || !isSVGSMILElement(*element)) { |
- condition->setSyncBase(0); |
- continue; |
- } |
- SVGSMILElement* svgSMILElement = toSVGSMILElement(element); |
- condition->setSyncBase(svgSMILElement); |
- svgSMILElement->addSyncBaseDependent(this); |
- } |
+ for (Condition* condition : m_conditions) { |
+ if (condition->getType() == Condition::Syncbase) |
+ condition->connectSyncBase(*this); |
} |
} |
@@ -551,63 +596,24 @@ void SVGSMILElement::disconnectSyncBaseConditions() { |
if (!m_syncBaseConditionsConnected) |
return; |
m_syncBaseConditionsConnected = false; |
- for (unsigned n = 0; n < m_conditions.size(); ++n) { |
- Condition* condition = m_conditions[n].get(); |
- if (condition->getType() == Condition::Syncbase) { |
- if (condition->syncBase()) |
- condition->syncBase()->removeSyncBaseDependent(this); |
- condition->setSyncBase(0); |
- } |
+ for (Condition* condition : m_conditions) { |
+ if (condition->getType() == Condition::Syncbase) |
+ condition->disconnectSyncBase(*this); |
} |
} |
void SVGSMILElement::connectEventBaseConditions() { |
disconnectEventBaseConditions(); |
- for (unsigned n = 0; n < m_conditions.size(); ++n) { |
- Condition* condition = m_conditions[n].get(); |
- if (condition->getType() == Condition::EventBase) { |
- ASSERT(!condition->syncBase()); |
- SVGElement* eventBase = eventBaseFor(*condition); |
- if (!eventBase) { |
- if (!condition->baseID().isEmpty() && |
- !treeScope() |
- .ensureSVGTreeScopedResources() |
- .isElementPendingResource(*this, |
- AtomicString(condition->baseID()))) { |
- treeScope().ensureSVGTreeScopedResources().addPendingResource( |
- AtomicString(condition->baseID()), *this); |
- } |
- continue; |
- } |
- ASSERT(!condition->eventListener()); |
- condition->setEventListener( |
- ConditionEventListener::create(this, condition)); |
- eventBase->addEventListener(AtomicString(condition->name()), |
- condition->eventListener(), false); |
- addReferenceTo(eventBase); |
- } |
+ for (Condition* condition : m_conditions) { |
+ if (condition->getType() == Condition::EventBase) |
+ condition->connectEventBase(*this); |
} |
} |
void SVGSMILElement::disconnectEventBaseConditions() { |
- for (unsigned n = 0; n < m_conditions.size(); ++n) { |
- Condition* condition = m_conditions[n].get(); |
- if (condition->getType() == Condition::EventBase) { |
- ASSERT(!condition->syncBase()); |
- if (!condition->eventListener()) |
- continue; |
- // Note: It's a memory optimization to try to remove our condition |
- // event listener, but it's not guaranteed to work, since we have |
- // no guarantee that eventBaseFor() will be able to find our condition's |
- // original eventBase. So, we also have to disconnect ourselves from |
- // our condition event listener, in case it later fires. |
- SVGElement* eventBase = eventBaseFor(*condition); |
- if (eventBase) |
- eventBase->removeEventListener(AtomicString(condition->name()), |
- condition->eventListener(), false); |
- condition->eventListener()->disconnectAnimation(); |
- condition->setEventListener(nullptr); |
- } |
+ for (Condition* condition : m_conditions) { |
+ if (condition->getType() == Condition::EventBase) |
+ condition->disconnectEventBase(*this); |
} |
} |
@@ -1183,26 +1189,25 @@ void SVGSMILElement::notifyDependentsIntervalChanged() { |
return; |
for (SVGSMILElement* element : m_syncBaseDependents) |
- element->createInstanceTimesFromSyncbase(this); |
+ element->createInstanceTimesFromSyncbase(*this); |
loopBreaker.erase(this); |
} |
-void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncBase) { |
+void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement& syncBase) { |
// FIXME: To be really correct, this should handle updating exising interval |
// by changing the associated times instead of creating new ones. |
- for (unsigned n = 0; n < m_conditions.size(); ++n) { |
- Condition* condition = m_conditions[n].get(); |
+ for (Condition* condition : m_conditions) { |
if (condition->getType() == Condition::Syncbase && |
- condition->syncBase() == syncBase) { |
+ condition->syncBaseEquals(syncBase)) { |
ASSERT(condition->name() == "begin" || condition->name() == "end"); |
// No nested time containers in SVG, no need for crazy time space |
// conversions. Phew! |
SMILTime time = 0; |
if (condition->name() == "begin") |
- time = syncBase->m_interval.begin + condition->offset(); |
+ time = syncBase.m_interval.begin + condition->offset(); |
else |
- time = syncBase->m_interval.end + condition->offset(); |
+ time = syncBase.m_interval.end + condition->offset(); |
if (!time.isFinite()) |
continue; |
SMILTime elapsed = this->elapsed(); |
@@ -1216,14 +1221,14 @@ void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncBase) { |
} |
} |
-void SVGSMILElement::addSyncBaseDependent(SVGSMILElement* animation) { |
- m_syncBaseDependents.insert(animation); |
+void SVGSMILElement::addSyncBaseDependent(SVGSMILElement& animation) { |
+ m_syncBaseDependents.insert(&animation); |
if (m_interval.begin.isFinite()) |
- animation->createInstanceTimesFromSyncbase(this); |
+ animation.createInstanceTimesFromSyncbase(*this); |
} |
-void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement* animation) { |
- m_syncBaseDependents.erase(animation); |
+void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement& animation) { |
+ m_syncBaseDependents.erase(&animation); |
} |
void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition) { |
@@ -1302,13 +1307,6 @@ void SVGSMILElement::unscheduleIfScheduled() { |
m_isScheduled = false; |
} |
-SVGSMILElement::Condition::~Condition() {} |
- |
-DEFINE_TRACE(SVGSMILElement::Condition) { |
- visitor->trace(m_syncBase); |
- visitor->trace(m_eventListener); |
-} |
- |
DEFINE_TRACE(SVGSMILElement) { |
visitor->trace(m_targetElement); |
visitor->trace(m_timeContainer); |