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

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

Issue 206603002: Add EventHandlerRegistry (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Refactoring WIP. Created 6 years, 9 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4 #include "config.h"
5 #include "core/dom/EventHandlerRegistry.h"
6
7 #include "core/dom/Document.h"
8 #include "core/events/ThreadLocalEventNames.h"
9 #include "core/events/WheelEvent.h"
10 #include "core/frame/FrameHost.h"
11 #include "core/frame/LocalFrame.h"
12 #include "core/page/Chrome.h"
13 #include "core/page/ChromeClient.h"
14 #include "core/page/Page.h"
15 #include "core/page/scrolling/ScrollingCoordinator.h"
16
17 namespace WebCore {
18
19 EventHandlerRegistry::EventHandlerRegistry(Document& document)
20 : DOMWindowLifecycleObserver(document.domWindow())
21 , m_scrollEventHandlerCount(0)
22 , m_wheelEventHandlerCount(0)
23 {
24 }
25
26 EventHandlerRegistry::~EventHandlerRegistry()
27 {
28 }
29
30 const char* EventHandlerRegistry::supplementName()
31 {
32 return "EventHandlerRegistry";
33 }
34
35 EventHandlerRegistry* EventHandlerRegistry::from(Document& document)
36 {
37 EventHandlerRegistry* controller = static_cast<EventHandlerRegistry*>(Docume ntSupplement::from(document, supplementName()));
38 if (!controller) {
39 controller = new EventHandlerRegistry(document);
40 DocumentSupplement::provideTo(document, supplementName(), adoptPtr(contr oller));
41 }
42 return controller;
43 }
44
45 void EventHandlerRegistry::didChangeWheelEventHandlerCount(Document& document, i nt delta)
46 {
47 if (delta < 0)
48 ASSERT(m_wheelEventHandlerCount > 0);
49 m_wheelEventHandlerCount += delta;
50
51 Page* page = document.page();
52 if (!page)
53 return;
54
55 LocalFrame* mainFrame = page->mainFrame();
56 if (mainFrame)
57 mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
58
59 ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
60 if (!scrollingCoordinator)
61 return;
62
63 FrameView* frameView = document.view();
64 if (!frameView)
65 return;
66
67 scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
68 }
69
70 void EventHandlerRegistry::didChangeScrollEventHandlerCount(Document& document, int delta)
71 {
72 if (delta < 0)
73 ASSERT(m_scrollEventHandlerCount > 0);
74 m_scrollEventHandlerCount += delta;
75
76 Page* page = document.page();
77 if (!page)
78 return;
79
80 ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
81 if (!scrollingCoordinator)
82 return;
83
84 FrameView* frameView = document.view();
85 if (!frameView)
86 return;
87
88 scrollingCoordinator->frameViewScrollEventHandlerCountChanged(frameView);
89 }
90
91 static void notifyTouchRectsChanged(Document& document)
92 {
93 Page* page = document.page();
94 if (!page)
95 return;
96
97 ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
98 if (!scrollingCoordinator)
99 return;
100
101 scrollingCoordinator->touchEventTargetRectsDidChange();
102 }
103
104 void EventHandlerRegistry::didAddTouchEventHandler(Document& document, Node& han dler)
105 {
106 // The node should either be in the document, or be the Document node of a c hild
107 // of the document.
108 ASSERT(&handler.document() == &document
109 || (handler.isDocumentNode() && toDocument(&handler)->parentDocument() = = &document));
110
111 if (!m_touchEventTargets.get())
112 m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
113 bool isFirstHandler = m_touchEventTargets->isEmpty();
114
115 if (!m_touchEventTargets->add(&handler).isNewEntry) {
116 // Just incremented refcount, no real change.
117 // If this is a child document node, then the count should never go abov e 1.
118 ASSERT(!handler.isDocumentNode() || &handler->document() == &document);
119 return;
120 }
121
122 if (isFirstHandler) {
123 if (Document* parent = document.parentDocument()) {
124 didAddTouchEventHandler(*parent, document);
125 } else {
126 // This is the first touch handler on the whole page.
127 if (FrameHost* frameHost = document.frameHost())
128 frameHost->chrome().client().needTouchEvents(true);
129 }
130 }
131
132 // When we're all done with all frames, ensure touch hit rects are marked as dirty.
133 if (!handler.isDocumentNode() || &handler == &document)
134 notifyTouchRectsChanged(document);
135 }
136
137 void EventHandlerRegistry::didRemoveTouchEventHandler(Document& document, Node& handler, bool clearAll)
138 {
139 // Note that we can't assert that |handler| is in this document because it m ight be in
140 // the process of moving out of it.
141 ASSERT(clearAll || m_touchEventTargets->contains(&handler));
142 if (!m_touchEventTargets.get())
143 return;
144
145 if (clearAll) {
146 if (!m_touchEventTargets->contains(&handler))
147 return;
148 m_touchEventTargets->removeAll(&handler);
149 } else {
150 if (!m_touchEventTargets->remove(&handler)) {
151 // Just decremented refcount, no real update.
152 return;
153 }
154 }
155
156 if (m_touchEventTargets->isEmpty()) {
157 if (Document* parent = document.parentDocument()) {
158 // This was the last handler in the document, update the parent docu ment too.
159 didRemoveTouchEventHandler(*parent, document, clearAll);
160 } else {
161 // We just removed the last touch handler on the whole page.
162 if (FrameHost* frameHost = document.frameHost())
163 frameHost->chrome().client().needTouchEvents(false);
164 }
165 }
166
167 // When we're all done with all frames, ensure touch hit rects are marked as dirty.
168 if (!handler.isDocumentNode() || &handler == &document)
169 notifyTouchRectsChanged(document);
170 }
171
172 void EventHandlerRegistry::didAddEventHandler(Document& document, const AtomicSt ring& eventType, Node* targetNode)
173 {
174 if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mouse wheel)
175 didChangeWheelEventHandlerCount(document, 1);
176 else if (eventType == EventTypeNames::scroll)
177 didChangeScrollEventHandlerCount(document, 1);
178 else if (isTouchEventType(eventType))
179 didAddTouchEventHandler(document, *targetNode);
180 }
181
182 void EventHandlerRegistry::didRemoveEventHandler(Document& document, const Atomi cString& eventType, Node* targetNode)
183 {
184 if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mouse wheel)
185 didChangeWheelEventHandlerCount(document, -1);
186 else if (eventType == EventTypeNames::scroll)
187 didChangeScrollEventHandlerCount(document, -1);
188 else if (isTouchEventType(eventType))
189 didRemoveTouchEventHandler(document, *targetNode, false);
190 }
191
192 void EventHandlerRegistry::didAddEventListener(DOMWindow* window, const AtomicSt ring& eventType)
193 {
194 didAddEventHandler(*window->document(), eventType, window->document());
195 }
196
197 void EventHandlerRegistry::didRemoveEventListener(DOMWindow* window, const Atomi cString& eventType)
198 {
199 didRemoveEventHandler(*window->document(), eventType, window->document());
200 }
201
202 void EventHandlerRegistry::didMoveNodeToNewDocument(Node& targetNode, Document& oldDocument)
203 {
204 didChangeAllEventHandlers(targetNode, oldDocument, Removed);
205 didChangeAllEventHandlers(targetNode, targetNode.document(), Added);
206 }
207
208 void EventHandlerRegistry::didRemoveAllEventHandlers(Node& targetNode)
209 {
210 didChangeAllEventHandlers(targetNode, targetNode.document(), RemovedAll);
211 }
212
213 void EventHandlerRegistry::didChangeAllEventHandlers(Node& targetNode, Document& document, ChangeOperation op)
214 {
215 if (!targetNode.hasEventListeners())
216 return;
217 EventHandlerRegistry* registry = EventHandlerRegistry::from(document);
218 int wheelHandlerCount = targetNode.getEventListeners(EventTypeNames::wheel). size() +
219 targetNode.getEventListeners(EventTypeNames::mousewheel).size();
220 registry->didChangeWheelEventHandlerCount(
221 document, (op == Added) ? wheelHandlerCount : -wheelHandlerCount);
222
223 int scrollHandlerCount = targetNode.getEventListeners(EventTypeNames::scroll ).size();
224 registry->didChangeScrollEventHandlerCount(
225 document, (op == Added) ? scrollHandlerCount : -scrollHandlerCount);
226
227 const Vector<AtomicString> eventTypes = targetNode.eventTypes();
228 for (size_t i = 0; i < eventTypes.size(); ++i) {
229 if (!isTouchEventType(eventTypes[i]))
230 continue;
231 const EventListenerVector& eventListeners =
232 targetNode.getEventListeners(eventTypes[i]);
233 for (size_t j = 0; j < eventListeners.size(); ++j) {
234 if (op == Added)
235 registry->didAddTouchEventHandler(document, targetNode);
236 else
237 registry->didRemoveTouchEventHandler(document, targetNode, op == RemovedAll);
238 }
239 }
240 }
241
242 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698