OLD | NEW |
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/frame/EventHandlerRegistry.h" | 6 #include "core/frame/EventHandlerRegistry.h" |
7 | 7 |
8 #include "core/events/ThreadLocalEventNames.h" | 8 #include "core/events/ThreadLocalEventNames.h" |
| 9 #include "core/frame/DOMWindow.h" |
| 10 #include "core/frame/LocalFrame.h" |
9 #include "core/html/HTMLFrameOwnerElement.h" | 11 #include "core/html/HTMLFrameOwnerElement.h" |
10 #include "core/page/Page.h" | 12 #include "core/page/Page.h" |
11 #include "core/page/scrolling/ScrollingCoordinator.h" | 13 #include "core/page/scrolling/ScrollingCoordinator.h" |
12 | 14 |
13 namespace WebCore { | 15 namespace WebCore { |
14 | 16 |
| 17 EventHandlerRegistry::WindowObserver::WindowObserver(EventHandlerRegistry& regis
try, DOMWindow& window) |
| 18 : DOMWindowLifecycleObserver(&window) |
| 19 , m_registry(registry) |
| 20 { |
| 21 } |
| 22 |
| 23 EventHandlerRegistry::WindowObserver::~WindowObserver() |
| 24 { |
| 25 } |
| 26 |
| 27 void EventHandlerRegistry::WindowObserver::didAddEventListener(DOMWindow* window
, const AtomicString& eventType) |
| 28 { |
| 29 m_registry.didAddEventHandler(*window, eventType); |
| 30 } |
| 31 |
| 32 void EventHandlerRegistry::WindowObserver::didRemoveEventListener(DOMWindow* win
dow, const AtomicString& eventType) |
| 33 { |
| 34 m_registry.didRemoveEventHandler(*window, eventType); |
| 35 } |
| 36 |
| 37 void EventHandlerRegistry::WindowObserver::didRemoveAllEventListeners(DOMWindow*
window) |
| 38 { |
| 39 m_registry.didRemoveAllEventHandlers(*window); |
| 40 } |
| 41 |
15 EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) | 42 EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) |
16 : m_frameHost(frameHost) | 43 : m_frameHost(frameHost) |
17 { | 44 { |
18 } | 45 } |
19 | 46 |
20 EventHandlerRegistry::~EventHandlerRegistry() | 47 EventHandlerRegistry::~EventHandlerRegistry() |
21 { | 48 { |
22 checkConsistency(); | 49 checkConsistency(); |
23 } | 50 } |
24 | 51 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 } | 136 } |
110 | 137 |
111 void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandl
erClass handlerClass) | 138 void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandl
erClass handlerClass) |
112 { | 139 { |
113 updateEventHandlerInternal(Remove, handlerClass, &target); | 140 updateEventHandlerInternal(Remove, handlerClass, &target); |
114 } | 141 } |
115 | 142 |
116 void EventHandlerRegistry::didMoveIntoFrameHost(EventTarget& target) | 143 void EventHandlerRegistry::didMoveIntoFrameHost(EventTarget& target) |
117 { | 144 { |
118 updateAllEventHandlers(Add, target); | 145 updateAllEventHandlers(Add, target); |
| 146 if (DOMWindow* window = target.toDOMWindow()) { |
| 147 ASSERT(!m_windowObservers.contains(window)); |
| 148 m_windowObservers.set(window, adoptPtr(new WindowObserver(*this, *window
))); |
| 149 } |
119 } | 150 } |
120 | 151 |
121 void EventHandlerRegistry::didMoveOutOfFrameHost(EventTarget& target) | 152 void EventHandlerRegistry::didMoveOutOfFrameHost(EventTarget& target) |
122 { | 153 { |
123 updateAllEventHandlers(RemoveAll, target); | 154 updateAllEventHandlers(RemoveAll, target); |
| 155 if (DOMWindow* window = target.toDOMWindow()) { |
| 156 ASSERT(m_windowObservers.contains(window)); |
| 157 m_windowObservers.remove(window); |
| 158 } |
124 } | 159 } |
125 | 160 |
126 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target) | 161 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target) |
127 { | 162 { |
128 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 163 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
129 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 164 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
130 updateEventHandlerInternal(RemoveAll, handlerClass, &target); | 165 updateEventHandlerInternal(RemoveAll, handlerClass, &target); |
131 } | 166 } |
132 } | 167 } |
133 | 168 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 204 } |
170 } | 205 } |
171 | 206 |
172 void EventHandlerRegistry::trace(Visitor* visitor) | 207 void EventHandlerRegistry::trace(Visitor* visitor) |
173 { | 208 { |
174 visitor->registerWeakMembers<EventHandlerRegistry, &EventHandlerRegistry::cl
earWeakMembers>(this); | 209 visitor->registerWeakMembers<EventHandlerRegistry, &EventHandlerRegistry::cl
earWeakMembers>(this); |
175 } | 210 } |
176 | 211 |
177 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) | 212 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) |
178 { | 213 { |
179 Vector<EventTarget*> deadNodeTargets; | 214 Vector<EventTarget*> deadTargets; |
180 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 215 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
181 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 216 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
182 const EventTargetSet* targets = &m_targets[handlerClass]; | 217 const EventTargetSet* targets = &m_targets[handlerClass]; |
183 for (EventTargetSet::const_iterator it = targets->begin(); it != targets
->end(); ++it) { | 218 for (EventTargetSet::const_iterator it = targets->begin(); it != targets
->end(); ++it) { |
184 Node* node = it->key->toNode(); | 219 Node* node = it->key->toNode(); |
185 if (node && !visitor->isAlive(node)) | 220 DOMWindow* window = it->key->toDOMWindow(); |
186 deadNodeTargets.append(node); | 221 if (node && !visitor->isAlive(node)) { |
| 222 deadTargets.append(node); |
| 223 } else if (window && !visitor->isAlive(window)) { |
| 224 deadTargets.append(window); |
| 225 } |
187 } | 226 } |
188 } | 227 } |
189 for (size_t i = 0; i < deadNodeTargets.size(); ++i) | 228 for (size_t i = 0; i < deadTargets.size(); ++i) |
190 didRemoveAllEventHandlers(*deadNodeTargets[i]); | 229 didRemoveAllEventHandlers(*deadTargets[i]); |
191 } | 230 } |
192 | 231 |
193 void EventHandlerRegistry::documentDetached(Document& document) | 232 void EventHandlerRegistry::documentDetached(Document& document) |
194 { | 233 { |
195 // Remove all event targets under the detached document. | 234 // Remove all event targets under the detached document. |
196 for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCoun
t; ++handlerClassIndex) { | 235 for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCoun
t; ++handlerClassIndex) { |
197 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerC
lassIndex); | 236 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerC
lassIndex); |
198 Vector<EventTarget*> targetsToRemove; | 237 Vector<EventTarget*> targetsToRemove; |
199 const EventTargetSet* targets = &m_targets[handlerClass]; | 238 const EventTargetSet* targets = &m_targets[handlerClass]; |
200 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { | 239 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { |
201 if (Node* node = iter->key->toNode()) { | 240 if (Node* node = iter->key->toNode()) { |
202 for (Document* doc = &node->document(); doc; doc = doc->ownerEle
ment() ? &doc->ownerElement()->document() : 0) { | 241 for (Document* doc = &node->document(); doc; doc = doc->ownerEle
ment() ? &doc->ownerElement()->document() : 0) { |
203 if (doc == &document) { | 242 if (doc == &document) { |
204 targetsToRemove.append(iter->key); | 243 targetsToRemove.append(iter->key); |
205 break; | 244 break; |
206 } | 245 } |
207 } | 246 } |
| 247 } else if (iter->key->toDOMWindow()) { |
| 248 // DOM windows may outlive their documents, so we should not |
| 249 // remove their handlers here. |
| 250 } else { |
| 251 ASSERT_NOT_REACHED(); |
208 } | 252 } |
209 } | 253 } |
210 for (size_t i = 0; i < targetsToRemove.size(); ++i) | 254 for (size_t i = 0; i < targetsToRemove.size(); ++i) |
211 updateEventHandlerInternal(RemoveAll, handlerClass, targetsToRemove[
i]); | 255 updateEventHandlerInternal(RemoveAll, handlerClass, targetsToRemove[
i]); |
212 } | 256 } |
213 } | 257 } |
214 | 258 |
215 void EventHandlerRegistry::checkConsistency() const | 259 void EventHandlerRegistry::checkConsistency() const |
216 { | 260 { |
217 #if ASSERT_ENABLED | 261 #if ASSERT_ENABLED |
218 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 262 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
219 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 263 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
220 const EventTargetSet* targets = &m_targets[handlerClass]; | 264 const EventTargetSet* targets = &m_targets[handlerClass]; |
221 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { | 265 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { |
| 266 // See the comment for |documentDetached| if any of these assertions
fail. |
222 if (Node* node = iter->key->toNode()) { | 267 if (Node* node = iter->key->toNode()) { |
223 // See the comment for |documentDetached| if either of these ass
ertions fails. | |
224 ASSERT(node->document().frameHost()); | 268 ASSERT(node->document().frameHost()); |
225 ASSERT(node->document().frameHost() == &m_frameHost); | 269 ASSERT(node->document().frameHost() == &m_frameHost); |
| 270 } else if (DOMWindow* window = iter->key->toDOMWindow()) { |
| 271 ASSERT(window->frame()); |
| 272 ASSERT(window->frame()->host()); |
| 273 ASSERT(window->frame()->host() == &m_frameHost); |
226 } | 274 } |
227 } | 275 } |
228 } | 276 } |
229 #endif // ASSERT_ENABLED | 277 #endif // ASSERT_ENABLED |
230 } | 278 } |
231 | 279 |
232 } // namespace WebCore | 280 } // namespace WebCore |
OLD | NEW |