Index: Source/WebCore/svg/SVGTRefElement.cpp |
=================================================================== |
--- Source/WebCore/svg/SVGTRefElement.cpp (revision 96953) |
+++ Source/WebCore/svg/SVGTRefElement.cpp (working copy) |
@@ -75,11 +75,14 @@ |
virtual bool operator==(const EventListener&); |
- void removeFromTarget() |
+ void clear() |
{ |
Element* target = m_trefElement->treeScope()->getElementById(m_targetId); |
if (target && target->parentNode()) |
target->parentNode()->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); |
+ |
+ m_trefElement = 0; |
+ m_targetId = String(); |
} |
private: |
@@ -105,7 +108,7 @@ |
void SubtreeModificationEventListener::handleEvent(ScriptExecutionContext*, Event* event) |
{ |
- if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement != event->target()) |
+ if (m_trefElement && event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement != event->target()) |
m_trefElement->updateReferencedText(); |
} |
@@ -138,6 +141,11 @@ |
return true; |
} |
+SVGTRefElement::~SVGTRefElement() |
+{ |
+ clearEventListener(); |
+} |
+ |
void SVGTRefElement::updateReferencedText() |
{ |
Element* target = SVGURIReference::targetElementFromIRIString(href(), document()); |
@@ -184,22 +192,7 @@ |
SVGElementInstance::InvalidationGuard invalidationGuard(this); |
if (SVGURIReference::isKnownAttribute(attrName)) { |
- if (m_eventListener) { |
- m_eventListener->removeFromTarget(); |
- m_eventListener = 0; |
- } |
- String id; |
- Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id); |
- if (!target) { |
- document()->accessSVGExtensions()->addPendingResource(id, this); |
- return; |
- } |
- updateReferencedText(); |
- if (inDocument()) { |
- m_eventListener = SubtreeModificationEventListener::create(this, id); |
- ASSERT(target->parentNode()); |
- target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false); |
- } |
+ buildPendingResource(); |
if (RenderObject* renderer = this->renderer()) |
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer); |
return; |
@@ -235,39 +228,50 @@ |
void SVGTRefElement::buildPendingResource() |
{ |
- updateReferencedText(); |
- if (Element* target = SVGURIReference::targetElementFromIRIString(href(), document())) { |
- ASSERT(!m_eventListener); |
- m_eventListener = SubtreeModificationEventListener::create(this, target->getIdAttribute()); |
- ASSERT(target->parentNode()); |
- target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false); |
- } |
-} |
+ // Remove any existing event listener. |
+ clearEventListener(); |
-void SVGTRefElement::insertedIntoDocument() |
-{ |
- SVGStyledElement::insertedIntoDocument(); |
String id; |
Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id); |
if (!target) { |
+ if (hasPendingResources() || id.isEmpty()) |
+ return; |
+ |
+ ASSERT(!hasPendingResources()); |
document()->accessSVGExtensions()->addPendingResource(id, this); |
+ ASSERT(hasPendingResources()); |
return; |
} |
+ |
updateReferencedText(); |
+ |
+ // We should not add the event listener if we are not in document yet. |
+ if (!inDocument()) |
+ return; |
+ |
m_eventListener = SubtreeModificationEventListener::create(this, id); |
ASSERT(target->parentNode()); |
target->parentNode()->addEventListener(eventNames().DOMSubtreeModifiedEvent, m_eventListener.get(), false); |
} |
+void SVGTRefElement::insertedIntoDocument() |
+{ |
+ SVGStyledElement::insertedIntoDocument(); |
+ buildPendingResource(); |
+} |
+ |
void SVGTRefElement::removedFromDocument() |
{ |
SVGStyledElement::removedFromDocument(); |
+ clearEventListener(); |
+} |
- if (!m_eventListener) |
- return; |
- |
- m_eventListener->removeFromTarget(); |
- m_eventListener = 0; |
+void SVGTRefElement::clearEventListener() |
+{ |
+ if (m_eventListener) { |
+ m_eventListener->clear(); |
+ m_eventListener = 0; |
+ } |
} |
} |