Index: Source/core/frame/EventHandlerRegistry.cpp |
diff --git a/Source/core/frame/EventHandlerRegistry.cpp b/Source/core/frame/EventHandlerRegistry.cpp |
index 0b57ec1f211f4d17e2b8ae8cc5258600eb7006ec..5161cf92e82630ebc6e88c224c7c0a09c99f858d 100644 |
--- a/Source/core/frame/EventHandlerRegistry.cpp |
+++ b/Source/core/frame/EventHandlerRegistry.cpp |
@@ -6,6 +6,8 @@ |
#include "core/frame/EventHandlerRegistry.h" |
#include "core/events/ThreadLocalEventNames.h" |
+#include "core/frame/DOMWindow.h" |
+#include "core/frame/LocalFrame.h" |
#include "core/html/HTMLFrameOwnerElement.h" |
#include "core/page/Page.h" |
#include "core/page/scrolling/ScrollingCoordinator.h" |
@@ -176,18 +178,22 @@ void EventHandlerRegistry::trace(Visitor* visitor) |
void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) |
{ |
- Vector<EventTarget*> deadNodeTargets; |
+ Vector<EventTarget*> deadTargets; |
for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
const EventTargetSet* targets = &m_targets[handlerClass]; |
for (EventTargetSet::const_iterator it = targets->begin(); it != targets->end(); ++it) { |
Node* node = it->key->toNode(); |
- if (node && !visitor->isAlive(node)) |
- deadNodeTargets.append(node); |
+ DOMWindow* window = it->key->toDOMWindow(); |
+ if (node && !visitor->isAlive(node)) { |
+ deadTargets.append(node); |
+ } else if (window && !visitor->isAlive(window)) { |
+ deadTargets.append(window); |
+ } |
} |
} |
- for (size_t i = 0; i < deadNodeTargets.size(); ++i) |
- didRemoveAllEventHandlers(*deadNodeTargets[i]); |
+ for (size_t i = 0; i < deadTargets.size(); ++i) |
+ didRemoveAllEventHandlers(*deadTargets[i]); |
} |
void EventHandlerRegistry::documentDetached(Document& document) |
@@ -205,6 +211,11 @@ void EventHandlerRegistry::documentDetached(Document& document) |
break; |
} |
} |
+ } else if (iter->key->toDOMWindow()) { |
+ // DOMWindows may outlive their documents, so we shouldn't remove their handlers |
+ // here. |
+ } else { |
+ ASSERT_NOT_REACHED(); |
} |
} |
for (size_t i = 0; i < targetsToRemove.size(); ++i) |
@@ -223,6 +234,12 @@ void EventHandlerRegistry::checkConsistency() const |
// See the comment for |documentDetached| if either of these assertions fails. |
ASSERT(node->document().frameHost()); |
ASSERT(node->document().frameHost() == &m_frameHost); |
+ } else if (DOMWindow* window = iter->key->toDOMWindow()) { |
+ // If any of these assertions fail, DOMWindow failed to unregister its handlers |
+ // properly. |
+ ASSERT(window->frame()); |
+ ASSERT(window->frame()->host()); |
+ ASSERT(window->frame()->host() == &m_frameHost); |
} |
} |
} |