Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: Source/core/dom/EventHandlerRegistry.cpp

Issue 237963014: Track scroll event handlers in nested documents (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: More simplification. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/EventHandlerRegistry.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/dom/EventHandlerRegistry.h" 6 #include "core/dom/EventHandlerRegistry.h"
7 7
8 #include "core/dom/Document.h" 8 #include "core/dom/Document.h"
9 #include "core/events/ThreadLocalEventNames.h" 9 #include "core/events/ThreadLocalEventNames.h"
10 #include "core/events/WheelEvent.h" 10 #include "core/events/WheelEvent.h"
11 #include "core/frame/FrameHost.h" 11 #include "core/frame/FrameHost.h"
12 #include "core/frame/LocalFrame.h" 12 #include "core/frame/LocalFrame.h"
13 #include "core/page/Chrome.h" 13 #include "core/page/Chrome.h"
14 #include "core/page/ChromeClient.h" 14 #include "core/page/ChromeClient.h"
15 #include "core/page/Page.h" 15 #include "core/page/Page.h"
16 #include "core/page/scrolling/ScrollingCoordinator.h" 16 #include "core/page/scrolling/ScrollingCoordinator.h"
17 17
18 namespace WebCore { 18 namespace WebCore {
19 19
20 EventHandlerRegistry::HandlerState::HandlerState() 20 EventHandlerRegistry::HandlerState::HandlerState()
21 { 21 {
22 } 22 }
23 23
24 EventHandlerRegistry::HandlerState::~HandlerState() 24 EventHandlerRegistry::HandlerState::~HandlerState()
25 { 25 {
26 } 26 }
27 27
28 EventHandlerRegistry::EventHandlerRegistry(Document& document) 28 EventHandlerRegistry::EventHandlerRegistry(Document& document)
29 : m_document(document) 29 : ActiveDOMObject(&document)
30 , m_document(document)
abarth-chromium 2014/04/23 15:23:28 We should be able to remove m_document now. Activ
Sami 2014/04/23 16:44:09 Ah, good idea, done.
30 { 31 {
31 } 32 }
32 33
33 EventHandlerRegistry::~EventHandlerRegistry() 34 EventHandlerRegistry::~EventHandlerRegistry()
34 { 35 {
35 } 36 }
36 37
37 const char* EventHandlerRegistry::supplementName() 38 const char* EventHandlerRegistry::supplementName()
38 { 39 {
39 return "EventHandlerRegistry"; 40 return "EventHandlerRegistry";
40 } 41 }
41 42
42 EventHandlerRegistry* EventHandlerRegistry::from(Document& document) 43 EventHandlerRegistry* EventHandlerRegistry::from(Document& document)
43 { 44 {
44 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Document Supplement::from(document, supplementName())); 45 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Document Supplement::from(document, supplementName()));
45 if (!registry) { 46 if (!registry) {
46 registry = new EventHandlerRegistry(document); 47 registry = new EventHandlerRegistry(document);
48 registry->suspendIfNeeded();
abarth-chromium 2014/04/23 15:23:28 Please add a static create function that does this
Sami 2014/04/23 16:44:09 Done.
47 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(regis try)); 49 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(regis try));
48 } 50 }
49 return registry; 51 return registry;
50 } 52 }
51 53
52 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result) 54 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result)
53 { 55 {
54 if (eventType == EventTypeNames::scroll) { 56 if (eventType == EventTypeNames::scroll) {
55 *result = ScrollEvent; 57 *result = ScrollEvent;
56 } else { 58 } else {
(...skipping 11 matching lines...) Expand all
68 { 70 {
69 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 71 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
70 return targets && targets->size(); 72 return targets && targets->size();
71 } 73 }
72 74
73 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target) 75 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target)
74 { 76 {
75 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 77 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
76 if (op == Add) { 78 if (op == Add) {
77 #if ASSERT_ENABLED 79 #if ASSERT_ENABLED
78 if (Node* node = target->toNode()) 80 if (Node* node = target->toNode()) {
79 ASSERT(&node->document() == &m_document); 81 // The node should either be in the document, or be the Document nod e of a child
82 // of the document.
83 ASSERT(&node->document() == &m_document
84 || (node->isDocumentNode() && toDocument(node)->parentDocument() == &m_document));
85 }
80 #endif // ASSERT_ENABLED 86 #endif // ASSERT_ENABLED
81 87
82 if (!targets) { 88 if (!targets) {
83 m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet) ; 89 m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet) ;
84 targets = m_eventHandlers[handlerClass].targets.get(); 90 targets = m_eventHandlers[handlerClass].targets.get();
85 } 91 }
86 92
87 if (!targets->add(target).isNewEntry) { 93 if (!targets->add(target).isNewEntry) {
88 // Just incremented refcount, no real change. 94 // Just incremented refcount, no real change.
95 #if ASSERT_ENABLED
96 // If this is a child document node, then the count should never go above 1.
97 if (Node* node = target->toNode())
98 ASSERT(!node->isDocumentNode() || &node->document() == &m_docume nt);
99 #endif // ASSERT_ENABLED
89 return false; 100 return false;
90 } 101 }
91 } else { 102 } else {
92 // Note that we can't assert that |target| is in this document because 103 // Note that we can't assert that |target| is in this document because
93 // it might be in the process of moving out of it. 104 // it might be in the process of moving out of it.
94 ASSERT(op == Remove || op == RemoveAll); 105 ASSERT(op == Remove || op == RemoveAll);
95 ASSERT(op == RemoveAll || targets->contains(target)); 106 ASSERT(op == RemoveAll || targets->contains(target));
96 if (!targets) 107 if (!targets)
97 return false; 108 return false;
98 109
99 if (op == RemoveAll) { 110 if (op == RemoveAll) {
100 if (!targets->contains(target)) 111 if (!targets->contains(target))
101 return false; 112 return false;
102 targets->removeAll(target); 113 targets->removeAll(target);
103 } else { 114 } else {
104 if (!targets->remove(target)) { 115 if (!targets->remove(target)) {
105 // Just decremented refcount, no real update. 116 // Just decremented refcount, no real update.
106 return false; 117 return false;
107 } 118 }
108 } 119 }
109 } 120 }
110 return true; 121 return true;
111 } 122 }
112 123
113 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target) 124 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target)
114 { 125 {
115 // After the document has stopped, all updates become no-ops. 126 // Notify our parent registry if we added the first or removed the last hand ler.
116 if (!m_document.isActive()) { 127 for (Document* document = &m_document; document; document = document->parent Document()) {
117 return; 128 // After the document has stopped, all updates become no-ops.
118 } 129 if (!document->isActive()) {
130 return;
131 }
abarth-chromium 2014/04/23 15:23:28 Is it possible for an active document to be contai
Sami 2014/04/23 16:44:09 Right, we can just check this at the leaf.
132 EventHandlerRegistry* registry = EventHandlerRegistry::from(*document);
119 133
120 bool hadHandlers = hasEventHandlers(handlerClass); 134 bool hadHandlers = registry->hasEventHandlers(handlerClass);
121 updateEventHandlerTargets(op, handlerClass, target); 135 registry->updateEventHandlerTargets(op, handlerClass, target);
abarth-chromium 2014/04/23 15:23:28 So, each registry knows about all the event listen
Sami 2014/04/23 16:44:09 No, each registry knows two things: 1) the set of
122 bool hasHandlers = hasEventHandlers(handlerClass); 136 bool hasHandlers = registry->hasEventHandlers(handlerClass);
123 137
124 // Notify the parent document's registry if we added the first or removed 138 if (hadHandlers == hasHandlers) {
125 // the last handler. 139 break;
126 if (hadHandlers != hasHandlers && !m_document.parentDocument()) { 140 }
127 // This is the root registry; notify clients accordingly. 141 if (!document->parentDocument()) {
128 notifyHasHandlersChanged(handlerClass, hasHandlers); 142 // This is the root registry; notify clients accordingly.
143 registry->notifyHasHandlersChanged(handlerClass, hasHandlers);
144 } else {
145 // Report change to parent with our Document as the target.
146 target = document;
147 }
129 } 148 }
130 } 149 }
131 150
132 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target) 151 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target)
133 { 152 {
134 EventHandlerClass handlerClass; 153 EventHandlerClass handlerClass;
135 if (!eventTypeToClass(eventType, &handlerClass)) 154 if (!eventTypeToClass(eventType, &handlerClass))
136 return; 155 return;
137 updateEventHandlerInternal(op, handlerClass, target); 156 updateEventHandlerInternal(op, handlerClass, target);
138 } 157 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 case ScrollEvent: 211 case ScrollEvent:
193 if (scrollingCoordinator) 212 if (scrollingCoordinator)
194 scrollingCoordinator->updateHaveScrollEventHandlers(); 213 scrollingCoordinator->updateHaveScrollEventHandlers();
195 break; 214 break;
196 default: 215 default:
197 ASSERT_NOT_REACHED(); 216 ASSERT_NOT_REACHED();
198 break; 217 break;
199 } 218 }
200 } 219 }
201 220
221 void EventHandlerRegistry::stop()
222 {
223 Document* parentDocument = m_document.parentDocument();
224 if (!parentDocument)
225 return;
226 EventHandlerRegistry* parentRegistry = EventHandlerRegistry::from(*parentDoc ument);
227 parentRegistry->didRemoveAllEventHandlers(m_document);
228 }
229
202 } // namespace WebCore 230 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/dom/EventHandlerRegistry.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698