Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(538)

Unified Diff: Source/core/svg/animation/SVGSMILElement.cpp

Issue 102353003: [SVG] Refactoring the logic to handle eventBase dependency (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fixed assert crash Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
« no previous file with comments | « Source/core/svg/animation/SVGSMILElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698