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

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: Cleanup. 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::create(Document& document)
29 {
30 EventHandlerRegistry* registry = new EventHandlerRegistry(document);
31 registry->suspendIfNeeded();
32 return registry;
33 }
34
28 EventHandlerRegistry::EventHandlerRegistry(Document& document) 35 EventHandlerRegistry::EventHandlerRegistry(Document& document)
29 : m_document(document) 36 : ActiveDOMObject(&document)
30 { 37 {
31 } 38 }
32 39
33 EventHandlerRegistry::~EventHandlerRegistry() 40 EventHandlerRegistry::~EventHandlerRegistry()
34 { 41 {
35 } 42 }
36 43
37 const char* EventHandlerRegistry::supplementName() 44 const char* EventHandlerRegistry::supplementName()
38 { 45 {
39 return "EventHandlerRegistry"; 46 return "EventHandlerRegistry";
40 } 47 }
41 48
49 Document* EventHandlerRegistry::document() const
50 {
51 return static_cast<Document*>(executionContext());
52 }
53
42 EventHandlerRegistry* EventHandlerRegistry::from(Document& document) 54 EventHandlerRegistry* EventHandlerRegistry::from(Document& document)
43 { 55 {
44 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Document Supplement::from(document, supplementName())); 56 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Document Supplement::from(document, supplementName()));
45 if (!registry) { 57 if (!registry) {
46 registry = new EventHandlerRegistry(document); 58 registry = create(document);
47 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(regis try)); 59 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(regis try));
48 } 60 }
49 return registry; 61 return registry;
50 } 62 }
51 63
52 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result) 64 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result)
53 { 65 {
54 if (eventType == EventTypeNames::scroll) { 66 if (eventType == EventTypeNames::scroll) {
55 *result = ScrollEvent; 67 *result = ScrollEvent;
56 } else { 68 } else {
(...skipping 11 matching lines...) Expand all
68 { 80 {
69 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 81 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
70 return targets && targets->size(); 82 return targets && targets->size();
71 } 83 }
72 84
73 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target) 85 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target)
74 { 86 {
75 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 87 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get();
76 if (op == Add) { 88 if (op == Add) {
77 #if ASSERT_ENABLED 89 #if ASSERT_ENABLED
78 if (Node* node = target->toNode()) 90 if (Node* node = target->toNode()) {
79 ASSERT(&node->document() == &m_document); 91 // The node should either be in the document, or be the Document nod e of a child
92 // of the document.
93 ASSERT(&node->document() == document()
94 || (node->isDocumentNode() && toDocument(node)->parentDocument() == document()));
95 }
80 #endif // ASSERT_ENABLED 96 #endif // ASSERT_ENABLED
81 97
82 if (!targets) { 98 if (!targets) {
83 m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet) ; 99 m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet) ;
84 targets = m_eventHandlers[handlerClass].targets.get(); 100 targets = m_eventHandlers[handlerClass].targets.get();
85 } 101 }
86 102
87 if (!targets->add(target).isNewEntry) { 103 if (!targets->add(target).isNewEntry) {
88 // Just incremented refcount, no real change. 104 // Just incremented refcount, no real change.
105 #if ASSERT_ENABLED
106 // If this is a child document node, then the count should never go above 1.
107 if (Node* node = target->toNode())
108 ASSERT(!node->isDocumentNode() || &node->document() == document( ));
109 #endif // ASSERT_ENABLED
89 return false; 110 return false;
90 } 111 }
91 } else { 112 } else {
92 // Note that we can't assert that |target| is in this document because 113 // 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. 114 // it might be in the process of moving out of it.
94 ASSERT(op == Remove || op == RemoveAll); 115 ASSERT(op == Remove || op == RemoveAll);
95 ASSERT(op == RemoveAll || targets->contains(target)); 116 ASSERT(op == RemoveAll || targets->contains(target));
96 if (!targets) 117 if (!targets)
97 return false; 118 return false;
98 119
99 if (op == RemoveAll) { 120 if (op == RemoveAll) {
100 if (!targets->contains(target)) 121 if (!targets->contains(target))
101 return false; 122 return false;
102 targets->removeAll(target); 123 targets->removeAll(target);
103 } else { 124 } else {
104 if (!targets->remove(target)) { 125 if (!targets->remove(target)) {
105 // Just decremented refcount, no real update. 126 // Just decremented refcount, no real update.
106 return false; 127 return false;
107 } 128 }
108 } 129 }
109 } 130 }
110 return true; 131 return true;
111 } 132 }
112 133
113 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target) 134 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target)
114 { 135 {
115 // After the document has stopped, all updates become no-ops. 136 // After the document has stopped, all updates become no-ops.
116 if (!m_document.isActive()) { 137 if (!document()->isActive())
117 return; 138 return;
118 }
119 139
120 bool hadHandlers = hasEventHandlers(handlerClass); 140 // Notify our parent registry if we added the first or removed the last hand ler.
121 updateEventHandlerTargets(op, handlerClass, target); 141 for (Document* document = this->document(); document; document = document->p arentDocument()) {
122 bool hasHandlers = hasEventHandlers(handlerClass); 142 EventHandlerRegistry* registry = EventHandlerRegistry::from(*document);
123 143
124 // Notify the parent document's registry if we added the first or removed 144 bool hadHandlers = registry->hasEventHandlers(handlerClass);
125 // the last handler. 145 registry->updateEventHandlerTargets(op, handlerClass, target);
126 if (hadHandlers != hasHandlers && !m_document.parentDocument()) { 146 bool hasHandlers = registry->hasEventHandlers(handlerClass);
127 // This is the root registry; notify clients accordingly. 147
128 notifyHasHandlersChanged(handlerClass, hasHandlers); 148 if (hadHandlers == hasHandlers) {
149 break;
150 }
151 if (!document->parentDocument()) {
152 // This is the root registry; notify clients accordingly.
153 registry->notifyHasHandlersChanged(handlerClass, hasHandlers);
154 } else {
155 // Report change to parent with our Document as the target.
156 target = document;
abarth-chromium 2014/04/23 17:25:54 I see, I missed this line.
157 }
129 } 158 }
130 } 159 }
131 160
132 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target) 161 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target)
133 { 162 {
134 EventHandlerClass handlerClass; 163 EventHandlerClass handlerClass;
135 if (!eventTypeToClass(eventType, &handlerClass)) 164 if (!eventTypeToClass(eventType, &handlerClass))
136 return; 165 return;
137 updateEventHandlerInternal(op, handlerClass, target); 166 updateEventHandlerInternal(op, handlerClass, target);
138 } 167 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); 207 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
179 const EventTargetSet* targets = eventHandlerTargets(handlerClass); 208 const EventTargetSet* targets = eventHandlerTargets(handlerClass);
180 if (!targets) 209 if (!targets)
181 continue; 210 continue;
182 updateEventHandlerInternal(RemoveAll, handlerClass, &target); 211 updateEventHandlerInternal(RemoveAll, handlerClass, &target);
183 } 212 }
184 } 213 }
185 214
186 void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerCla ss, bool hasActiveHandlers) 215 void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerCla ss, bool hasActiveHandlers)
187 { 216 {
188 Page* page = m_document.page(); 217 Page* page = document()->page();
189 ScrollingCoordinator* scrollingCoordinator = page ? page->scrollingCoordinat or() : 0; 218 ScrollingCoordinator* scrollingCoordinator = page ? page->scrollingCoordinat or() : 0;
190 219
191 switch (handlerClass) { 220 switch (handlerClass) {
192 case ScrollEvent: 221 case ScrollEvent:
193 if (scrollingCoordinator) 222 if (scrollingCoordinator)
194 scrollingCoordinator->updateHaveScrollEventHandlers(); 223 scrollingCoordinator->updateHaveScrollEventHandlers();
195 break; 224 break;
196 default: 225 default:
197 ASSERT_NOT_REACHED(); 226 ASSERT_NOT_REACHED();
198 break; 227 break;
199 } 228 }
200 } 229 }
201 230
231 void EventHandlerRegistry::stop()
232 {
233 Document* parentDocument = document()->parentDocument();
234 if (!parentDocument)
235 return;
236 EventHandlerRegistry* parentRegistry = EventHandlerRegistry::from(*parentDoc ument);
237 parentRegistry->didRemoveAllEventHandlers(*document());
238 }
239
202 } // namespace WebCore 240 } // 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