| Index: Source/core/frame/EventHandlerRegistry.cpp
|
| diff --git a/Source/core/frame/EventHandlerRegistry.cpp b/Source/core/frame/EventHandlerRegistry.cpp
|
| index 0b57ec1f211f4d17e2b8ae8cc5258600eb7006ec..50da14fc8198f5c58e58b44eaed9d83d4f625028 100644
|
| --- a/Source/core/frame/EventHandlerRegistry.cpp
|
| +++ b/Source/core/frame/EventHandlerRegistry.cpp
|
| @@ -6,12 +6,39 @@
|
| #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"
|
|
|
| namespace WebCore {
|
|
|
| +EventHandlerRegistry::WindowObserver::WindowObserver(EventHandlerRegistry& registry, DOMWindow& window)
|
| + : DOMWindowLifecycleObserver(&window)
|
| + , m_registry(registry)
|
| +{
|
| +}
|
| +
|
| +EventHandlerRegistry::WindowObserver::~WindowObserver()
|
| +{
|
| +}
|
| +
|
| +void EventHandlerRegistry::WindowObserver::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
|
| +{
|
| + m_registry.didAddEventHandler(*window, eventType);
|
| +}
|
| +
|
| +void EventHandlerRegistry::WindowObserver::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
|
| +{
|
| + m_registry.didRemoveEventHandler(*window, eventType);
|
| +}
|
| +
|
| +void EventHandlerRegistry::WindowObserver::didRemoveAllEventListeners(DOMWindow* window)
|
| +{
|
| + m_registry.didRemoveAllEventHandlers(*window);
|
| +}
|
| +
|
| EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost)
|
| : m_frameHost(frameHost)
|
| {
|
| @@ -116,11 +143,19 @@ void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandl
|
| void EventHandlerRegistry::didMoveIntoFrameHost(EventTarget& target)
|
| {
|
| updateAllEventHandlers(Add, target);
|
| + if (DOMWindow* window = target.toDOMWindow()) {
|
| + ASSERT(!m_windowObservers.contains(window));
|
| + m_windowObservers.set(window, adoptPtr(new WindowObserver(*this, *window)));
|
| + }
|
| }
|
|
|
| void EventHandlerRegistry::didMoveOutOfFrameHost(EventTarget& target)
|
| {
|
| updateAllEventHandlers(RemoveAll, target);
|
| + if (DOMWindow* window = target.toDOMWindow()) {
|
| + ASSERT(m_windowObservers.contains(window));
|
| + m_windowObservers.remove(window);
|
| + }
|
| }
|
|
|
| void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target)
|
| @@ -176,18 +211,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 +244,11 @@ void EventHandlerRegistry::documentDetached(Document& document)
|
| break;
|
| }
|
| }
|
| + } else if (iter->key->toDOMWindow()) {
|
| + // DOM windows may outlive their documents, so we should not
|
| + // remove their handlers here.
|
| + } else {
|
| + ASSERT_NOT_REACHED();
|
| }
|
| }
|
| for (size_t i = 0; i < targetsToRemove.size(); ++i)
|
| @@ -219,10 +263,14 @@ void EventHandlerRegistry::checkConsistency() const
|
| EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
|
| const EventTargetSet* targets = &m_targets[handlerClass];
|
| for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
|
| + // See the comment for |documentDetached| if any of these assertions fail.
|
| if (Node* node = iter->key->toNode()) {
|
| - // 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()) {
|
| + ASSERT(window->frame());
|
| + ASSERT(window->frame()->host());
|
| + ASSERT(window->frame()->host() == &m_frameHost);
|
| }
|
| }
|
| }
|
|
|