Chromium Code Reviews| Index: Source/core/dom/EventHandlerRegistry.cpp |
| diff --git a/Source/core/dom/EventHandlerRegistry.cpp b/Source/core/dom/EventHandlerRegistry.cpp |
| index b72b465ffaadc0a31187c14559227570e38b81e7..30f06dfbdcdc7b8a756feb45a6f7060e95d97004 100644 |
| --- a/Source/core/dom/EventHandlerRegistry.cpp |
| +++ b/Source/core/dom/EventHandlerRegistry.cpp |
| @@ -17,6 +17,26 @@ |
| namespace WebCore { |
| +EventHandlerRegistry::DocumentObserver::DocumentObserver(Document& document) |
| + : ActiveDOMObject(&document) |
| +{ |
| + suspendIfNeeded(); |
|
abarth-chromium
2014/04/22 16:18:23
As a general pattern, we don't call suspendIfNeede
Sami
2014/04/22 18:05:18
Okay, it sounds like I can move the call to suspen
|
| +} |
| + |
| +EventHandlerRegistry::DocumentObserver::~DocumentObserver() |
| +{ |
| +} |
| + |
| +void EventHandlerRegistry::DocumentObserver::stop() |
| +{ |
| + Document* document = static_cast<Document*>(lifecycleContext()); |
| + Document* parentDocument = document->parentDocument(); |
| + if (!parentDocument) |
| + return; |
| + EventHandlerRegistry* parentRegistry = EventHandlerRegistry::from(*parentDocument); |
| + parentRegistry->didRemoveAllEventHandlers(*document); |
| +} |
| + |
| EventHandlerRegistry::HandlerState::HandlerState() |
| { |
| } |
| @@ -27,6 +47,7 @@ EventHandlerRegistry::HandlerState::~HandlerState() |
| EventHandlerRegistry::EventHandlerRegistry(Document& document) |
| : m_document(document) |
| + , m_documentObserver(DocumentObserver(document)) |
| { |
|
abarth-chromium
2014/04/22 16:18:23
What's the point of having a separate DocumentObse
Sami
2014/04/22 18:05:18
First, it better isolates the implementation from
|
| } |
| @@ -75,8 +96,12 @@ bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa |
| EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); |
| if (op == Add) { |
| #if ASSERT_ENABLED |
| - if (Node* node = target->toNode()) |
| - ASSERT(&node->document() == &m_document); |
| + if (Node* node = target->toNode()) { |
| + // The node should either be in the document, or be the Document node of a child |
| + // of the document. |
| + ASSERT(&node->document() == &m_document |
| + || (node->isDocumentNode() && toDocument(node)->parentDocument() == &m_document)); |
| + } |
| #endif // ASSERT_ENABLED |
| if (!targets) { |
| @@ -86,6 +111,11 @@ bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa |
| if (!targets->add(target).isNewEntry) { |
| // Just incremented refcount, no real change. |
| +#if ASSERT_ENABLED |
| + // If this is a child document node, then the count should never go above 1. |
| + if (Node* node = target->toNode()) |
| + ASSERT(!node->isDocumentNode() || &node->document() == &m_document); |
| +#endif // ASSERT_ENABLED |
| return false; |
| } |
| } else { |
| @@ -123,9 +153,14 @@ void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH |
| // Notify the parent document's registry if we added the first or removed |
| // the last handler. |
| - if (hadHandlers != hasHandlers && !m_document.parentDocument()) { |
| - // This is the root registry; notify clients accordingly. |
| - notifyHasHandlersChanged(handlerClass, hasHandlers); |
| + if (hadHandlers != hasHandlers) { |
| + if (Document* parent = m_document.parentDocument()) { |
| + // Report change to parent with our Document as the target. |
| + EventHandlerRegistry::from(*parent)->updateEventHandlerInternal(op, handlerClass, &m_document); |
| + } else { |
| + // This is the root registry; notify clients accordingly. |
| + notifyHasHandlersChanged(handlerClass, hasHandlers); |
| + } |
|
abarth-chromium
2014/04/22 16:18:23
Can we implement this algorithm iteratively instea
Sami
2014/04/22 18:05:18
Sure, done. I'm having trouble deciding which way
|
| } |
| } |