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

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

Issue 237963014: Track scroll event handlers in nested documents (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Removed unneeded function definition. 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
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/page/EventHandlerRegistry.h"
7 7
8 #include "core/dom/Document.h"
9 #include "core/events/ThreadLocalEventNames.h" 8 #include "core/events/ThreadLocalEventNames.h"
10 #include "core/events/WheelEvent.h"
11 #include "core/frame/FrameHost.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/page/Chrome.h"
14 #include "core/page/ChromeClient.h"
15 #include "core/page/Page.h"
16 #include "core/page/scrolling/ScrollingCoordinator.h" 9 #include "core/page/scrolling/ScrollingCoordinator.h"
17 10
18 namespace WebCore { 11 namespace WebCore {
19 12
20 EventHandlerRegistry::HandlerState::HandlerState() 13 EventHandlerRegistry::EventHandlerRegistry(Page& page)
14 : m_page(page)
21 { 15 {
22 } 16 }
23 17
24 EventHandlerRegistry::HandlerState::~HandlerState()
25 {
26 }
27
28 EventHandlerRegistry::EventHandlerRegistry(Document& document)
29 : m_document(document)
30 {
31 }
32
33 EventHandlerRegistry::~EventHandlerRegistry() 18 EventHandlerRegistry::~EventHandlerRegistry()
34 { 19 {
35 } 20 }
36 21
37 const char* EventHandlerRegistry::supplementName() 22 const char* EventHandlerRegistry::supplementName()
38 { 23 {
39 return "EventHandlerRegistry"; 24 return "EventHandlerRegistry";
40 } 25 }
41 26
42 EventHandlerRegistry* EventHandlerRegistry::from(Document& document) 27 EventHandlerRegistry* EventHandlerRegistry::from(Page& page)
43 { 28 {
44 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Document Supplement::from(document, supplementName())); 29 EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(Suppleme nt<Page>::from(page, supplementName()));
45 if (!registry) { 30 if (!registry) {
46 registry = new EventHandlerRegistry(document); 31 registry = new EventHandlerRegistry(page);
47 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(regis try)); 32 Supplement<Page>::provideTo(page, supplementName(), adoptPtr(registry));
48 } 33 }
49 return registry; 34 return registry;
50 } 35 }
51 36
52 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result) 37 bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, Event HandlerClass* result)
53 { 38 {
54 if (eventType == EventTypeNames::scroll) { 39 if (eventType == EventTypeNames::scroll) {
55 *result = ScrollEvent; 40 *result = ScrollEvent;
56 } else { 41 } else {
57 return false; 42 return false;
58 } 43 }
59 return true; 44 return true;
60 } 45 }
61 46
62 const EventTargetSet* EventHandlerRegistry::eventHandlerTargets(EventHandlerClas s handlerClass) const 47 const EventTargetSet* EventHandlerRegistry::eventHandlerTargets(EventHandlerClas s handlerClass) const
63 { 48 {
64 return m_eventHandlers[handlerClass].targets.get(); 49 return &m_targets[handlerClass];
65 } 50 }
66 51
67 bool EventHandlerRegistry::hasEventHandlers(EventHandlerClass handlerClass) cons t 52 bool EventHandlerRegistry::hasEventHandlers(EventHandlerClass handlerClass) cons t
68 { 53 {
69 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 54 return m_targets[handlerClass].size();
70 return targets && targets->size();
71 } 55 }
72 56
73 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target) 57 bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHa ndlerClass handlerClass, EventTarget* target)
74 { 58 {
75 EventTargetSet* targets = m_eventHandlers[handlerClass].targets.get(); 59 EventTargetSet* targets = &m_targets[handlerClass];
76 if (op == Add) { 60 if (op == Add) {
77 #if ASSERT_ENABLED
78 if (Node* node = target->toNode())
79 ASSERT(&node->document() == &m_document);
80 #endif // ASSERT_ENABLED
81
82 if (!targets) {
83 m_eventHandlers[handlerClass].targets = adoptPtr(new EventTargetSet) ;
84 targets = m_eventHandlers[handlerClass].targets.get();
85 }
86
87 if (!targets->add(target).isNewEntry) { 61 if (!targets->add(target).isNewEntry) {
88 // Just incremented refcount, no real change. 62 // Just incremented refcount, no real change.
89 return false; 63 return false;
90 } 64 }
91 } else { 65 } else {
92 // Note that we can't assert that |target| is in this document because 66 // Note that we can't assert that |target| is in this document because
Rick Byers 2014/04/24 21:30:12 nit: remove/update comment (no "this document" any
Sami 2014/04/25 19:51:15 Good find, done.
93 // it might be in the process of moving out of it. 67 // it might be in the process of moving out of it.
94 ASSERT(op == Remove || op == RemoveAll); 68 ASSERT(op == Remove || op == RemoveAll);
95 ASSERT(op == RemoveAll || targets->contains(target)); 69 ASSERT(op == RemoveAll || targets->contains(target));
96 if (!targets)
97 return false;
98 70
99 if (op == RemoveAll) { 71 if (op == RemoveAll) {
100 if (!targets->contains(target)) 72 if (!targets->contains(target))
101 return false; 73 return false;
102 targets->removeAll(target); 74 targets->removeAll(target);
103 } else { 75 } else {
104 if (!targets->remove(target)) { 76 if (!targets->remove(target)) {
105 // Just decremented refcount, no real update. 77 // Just decremented refcount, no real update.
106 return false; 78 return false;
107 } 79 }
108 } 80 }
109 } 81 }
110 return true; 82 return true;
111 } 83 }
112 84
113 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target) 85 void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventH andlerClass handlerClass, EventTarget* target)
114 { 86 {
115 // After the document has stopped, all updates become no-ops.
116 if (!m_document.isActive()) {
117 return;
118 }
119
120 bool hadHandlers = hasEventHandlers(handlerClass); 87 bool hadHandlers = hasEventHandlers(handlerClass);
121 updateEventHandlerTargets(op, handlerClass, target); 88 updateEventHandlerTargets(op, handlerClass, target);
122 bool hasHandlers = hasEventHandlers(handlerClass); 89 bool hasHandlers = hasEventHandlers(handlerClass);
123 90
124 // Notify the parent document's registry if we added the first or removed 91 if (hadHandlers != hasHandlers) {
125 // the last handler.
126 if (hadHandlers != hasHandlers && !m_document.parentDocument()) {
127 // This is the root registry; notify clients accordingly.
128 notifyHasHandlersChanged(handlerClass, hasHandlers); 92 notifyHasHandlersChanged(handlerClass, hasHandlers);
129 } 93 }
130 } 94 }
131 95
132 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target) 96 void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const At omicString& eventType, EventTarget* target)
133 { 97 {
134 EventHandlerClass handlerClass; 98 EventHandlerClass handlerClass;
135 if (!eventTypeToClass(eventType, &handlerClass)) 99 if (!eventTypeToClass(eventType, &handlerClass))
136 return; 100 return;
137 updateEventHandlerInternal(op, handlerClass, target); 101 updateEventHandlerInternal(op, handlerClass, target);
(...skipping 14 matching lines...) Expand all
152 updateEventHandlerInternal(Add, handlerClass, &target); 116 updateEventHandlerInternal(Add, handlerClass, &target);
153 } 117 }
154 118
155 void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandl erClass handlerClass) 119 void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandl erClass handlerClass)
156 { 120 {
157 updateEventHandlerInternal(Remove, handlerClass, &target); 121 updateEventHandlerInternal(Remove, handlerClass, &target);
158 } 122 }
159 123
160 void EventHandlerRegistry::didMoveFromOtherDocument(EventTarget& target, Documen t& oldDocument) 124 void EventHandlerRegistry::didMoveFromOtherDocument(EventTarget& target, Documen t& oldDocument)
161 { 125 {
162 EventHandlerRegistry* oldRegistry = EventHandlerRegistry::from(oldDocument); 126 if (!oldDocument.page())
127 return;
128 EventHandlerRegistry* oldRegistry = EventHandlerRegistry::from(*oldDocument. page());
129 if (oldRegistry == this)
Rick Byers 2014/04/24 21:30:12 Do you know in what scenarios this won't be true?
Sami 2014/04/25 19:51:15 No, I don't have evidence whether this can actuall
130 return;
163 for (size_t i = 0; i < EventHandlerClassCount; ++i) { 131 for (size_t i = 0; i < EventHandlerClassCount; ++i) {
164 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); 132 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
165 const EventTargetSet* targets = oldRegistry->eventHandlerTargets(handler Class); 133 const EventTargetSet* targets = oldRegistry->eventHandlerTargets(handler Class);
166 if (!targets) 134 if (!targets)
167 continue; 135 continue;
168 for (unsigned count = targets->count(&target); count > 0; --count) { 136 for (unsigned count = targets->count(&target); count > 0; --count) {
169 oldRegistry->updateEventHandlerInternal(Remove, handlerClass, &targe t); 137 oldRegistry->updateEventHandlerInternal(Remove, handlerClass, &targe t);
170 updateEventHandlerInternal(Add, handlerClass, &target); 138 updateEventHandlerInternal(Add, handlerClass, &target);
171 } 139 }
172 } 140 }
173 } 141 }
174 142
175 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target) 143 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target)
176 { 144 {
177 for (size_t i = 0; i < EventHandlerClassCount; ++i) { 145 for (size_t i = 0; i < EventHandlerClassCount; ++i) {
178 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); 146 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
179 const EventTargetSet* targets = eventHandlerTargets(handlerClass);
180 if (!targets)
181 continue;
182 updateEventHandlerInternal(RemoveAll, handlerClass, &target); 147 updateEventHandlerInternal(RemoveAll, handlerClass, &target);
183 } 148 }
184 } 149 }
185 150
186 void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerCla ss, bool hasActiveHandlers) 151 void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerCla ss, bool hasActiveHandlers)
187 { 152 {
188 Page* page = m_document.page(); 153 ScrollingCoordinator* scrollingCoordinator = m_page.scrollingCoordinator();
189 ScrollingCoordinator* scrollingCoordinator = page ? page->scrollingCoordinat or() : 0;
190 154
191 switch (handlerClass) { 155 switch (handlerClass) {
192 case ScrollEvent: 156 case ScrollEvent:
193 if (scrollingCoordinator) 157 if (scrollingCoordinator)
194 scrollingCoordinator->updateHaveScrollEventHandlers(); 158 scrollingCoordinator->updateHaveScrollEventHandlers();
195 break; 159 break;
196 default: 160 default:
197 ASSERT_NOT_REACHED(); 161 ASSERT_NOT_REACHED();
198 break; 162 break;
199 } 163 }
200 } 164 }
201 165
202 } // namespace WebCore 166 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698