Copied: branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash-expected.txt (from rev 96707, trunk/LayoutTests/svg/text/tref-event-listener-crash-expected.txt) (0 => 96954)
--- branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash-expected.txt (rev 0)
+++ branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash-expected.txt 2011-10-07 17:12:30 UTC (rev 96954)
@@ -0,0 +1 @@
+Test passes if it does not crash.
Copied: branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash.svg (from rev 96707, trunk/LayoutTests/svg/text/tref-event-listener-crash.svg) (0 => 96954)
--- branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash.svg (rev 0)
+++ branches/chromium/874/LayoutTests/svg/text/tref-event-listener-crash.svg 2011-10-07 17:12:30 UTC (rev 96954)
@@ -0,0 +1,15 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+Test passes if it does not crash.
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="container">
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+window._onload_ = function() {
+ document.getElementById("container").textContent = "1";
+}
+</script>
+<desc id="test-desc"></desc>
+<tref xlink:href=""
+</svg>
+</html>
\ No newline at end of file
Modified: branches/chromium/874/Source/WebCore/svg/SVGTRefElement.cpp (96953 => 96954)
--- branches/chromium/874/Source/WebCore/svg/SVGTRefElement.cpp 2011-10-07 17:02:48 UTC (rev 96953)
+++ branches/chromium/874/Source/WebCore/svg/SVGTRefElement.cpp 2011-10-07 17:12:30 UTC (rev 96954)
@@ -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;
+ }
}
}
Modified: branches/chromium/874/Source/WebCore/svg/SVGTRefElement.h (96953 => 96954)
--- branches/chromium/874/Source/WebCore/svg/SVGTRefElement.h 2011-10-07 17:02:48 UTC (rev 96953)
+++ branches/chromium/874/Source/WebCore/svg/SVGTRefElement.h 2011-10-07 17:12:30 UTC (rev 96954)
@@ -38,6 +38,7 @@
friend class SubtreeModificationEventListener;
SVGTRefElement(const QualifiedName&, Document*);
+ virtual ~SVGTRefElement();
bool isSupportedAttribute(const QualifiedName&);
virtual void parseMappedAttribute(Attribute*);
@@ -50,6 +51,8 @@
virtual void insertedIntoDocument();
virtual void removedFromDocument();
+ void clearEventListener();
+
void updateReferencedText();
virtual void buildPendingResource();
Modified: branches/chromium/874/Source/WebCore/svg/SVGTextPathElement.cpp (96953 => 96954)
--- branches/chromium/874/Source/WebCore/svg/SVGTextPathElement.cpp 2011-10-07 17:02:48 UTC (rev 96953)
+++ branches/chromium/874/Source/WebCore/svg/SVGTextPathElement.cpp 2011-10-07 17:12:30 UTC (rev 96954)
@@ -145,7 +145,12 @@
String id;
Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
if (!targetElement) {
+ if (hasPendingResources() || id.isEmpty())
+ return;
+
+ ASSERT(!hasPendingResources());
document()->accessSVGExtensions()->addPendingResource(id, this);
+ ASSERT(hasPendingResources());
return;
}
}