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 |
15 EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) | 17 EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) |
16 : m_frameHost(frameHost) | 18 : m_frameHost(frameHost) |
17 { | 19 { |
18 } | 20 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 171 } |
170 } | 172 } |
171 | 173 |
172 void EventHandlerRegistry::trace(Visitor* visitor) | 174 void EventHandlerRegistry::trace(Visitor* visitor) |
173 { | 175 { |
174 visitor->registerWeakMembers<EventHandlerRegistry, &EventHandlerRegistry::cl
earWeakMembers>(this); | 176 visitor->registerWeakMembers<EventHandlerRegistry, &EventHandlerRegistry::cl
earWeakMembers>(this); |
175 } | 177 } |
176 | 178 |
177 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) | 179 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) |
178 { | 180 { |
179 Vector<EventTarget*> deadNodeTargets; | 181 Vector<EventTarget*> deadTargets; |
180 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 182 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
181 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 183 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
182 const EventTargetSet* targets = &m_targets[handlerClass]; | 184 const EventTargetSet* targets = &m_targets[handlerClass]; |
183 for (EventTargetSet::const_iterator it = targets->begin(); it != targets
->end(); ++it) { | 185 for (EventTargetSet::const_iterator it = targets->begin(); it != targets
->end(); ++it) { |
184 Node* node = it->key->toNode(); | 186 Node* node = it->key->toNode(); |
185 if (node && !visitor->isAlive(node)) | 187 DOMWindow* window = it->key->toDOMWindow(); |
186 deadNodeTargets.append(node); | 188 if (node && !visitor->isAlive(node)) { |
| 189 deadTargets.append(node); |
| 190 } else if (window && !visitor->isAlive(window)) { |
| 191 deadTargets.append(window); |
| 192 } |
187 } | 193 } |
188 } | 194 } |
189 for (size_t i = 0; i < deadNodeTargets.size(); ++i) | 195 for (size_t i = 0; i < deadTargets.size(); ++i) |
190 didRemoveAllEventHandlers(*deadNodeTargets[i]); | 196 didRemoveAllEventHandlers(*deadTargets[i]); |
191 } | 197 } |
192 | 198 |
193 void EventHandlerRegistry::documentDetached(Document& document) | 199 void EventHandlerRegistry::documentDetached(Document& document) |
194 { | 200 { |
195 // Remove all event targets under the detached document. | 201 // Remove all event targets under the detached document. |
196 for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCoun
t; ++handlerClassIndex) { | 202 for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCoun
t; ++handlerClassIndex) { |
197 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerC
lassIndex); | 203 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerC
lassIndex); |
198 Vector<EventTarget*> targetsToRemove; | 204 Vector<EventTarget*> targetsToRemove; |
199 const EventTargetSet* targets = &m_targets[handlerClass]; | 205 const EventTargetSet* targets = &m_targets[handlerClass]; |
200 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { | 206 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { |
201 if (Node* node = iter->key->toNode()) { | 207 if (Node* node = iter->key->toNode()) { |
202 for (Document* doc = &node->document(); doc; doc = doc->ownerEle
ment() ? &doc->ownerElement()->document() : 0) { | 208 for (Document* doc = &node->document(); doc; doc = doc->ownerEle
ment() ? &doc->ownerElement()->document() : 0) { |
203 if (doc == &document) { | 209 if (doc == &document) { |
204 targetsToRemove.append(iter->key); | 210 targetsToRemove.append(iter->key); |
205 break; | 211 break; |
206 } | 212 } |
207 } | 213 } |
| 214 } else if (iter->key->toDOMWindow()) { |
| 215 // DOMWindows may outlive their documents, so we shouldn't remov
e their handlers |
| 216 // here. |
| 217 } else { |
| 218 ASSERT_NOT_REACHED(); |
208 } | 219 } |
209 } | 220 } |
210 for (size_t i = 0; i < targetsToRemove.size(); ++i) | 221 for (size_t i = 0; i < targetsToRemove.size(); ++i) |
211 updateEventHandlerInternal(RemoveAll, handlerClass, targetsToRemove[
i]); | 222 updateEventHandlerInternal(RemoveAll, handlerClass, targetsToRemove[
i]); |
212 } | 223 } |
213 } | 224 } |
214 | 225 |
215 void EventHandlerRegistry::checkConsistency() const | 226 void EventHandlerRegistry::checkConsistency() const |
216 { | 227 { |
217 #if ASSERT_ENABLED | 228 #if ASSERT_ENABLED |
218 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 229 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
219 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 230 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
220 const EventTargetSet* targets = &m_targets[handlerClass]; | 231 const EventTargetSet* targets = &m_targets[handlerClass]; |
221 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { | 232 for (EventTargetSet::const_iterator iter = targets->begin(); iter != tar
gets->end(); ++iter) { |
222 if (Node* node = iter->key->toNode()) { | 233 if (Node* node = iter->key->toNode()) { |
223 // See the comment for |documentDetached| if either of these ass
ertions fails. | 234 // See the comment for |documentDetached| if either of these ass
ertions fails. |
224 ASSERT(node->document().frameHost()); | 235 ASSERT(node->document().frameHost()); |
225 ASSERT(node->document().frameHost() == &m_frameHost); | 236 ASSERT(node->document().frameHost() == &m_frameHost); |
| 237 } else if (DOMWindow* window = iter->key->toDOMWindow()) { |
| 238 // If any of these assertions fail, DOMWindow failed to unregist
er its handlers |
| 239 // properly. |
| 240 ASSERT(window->frame()); |
| 241 ASSERT(window->frame()->host()); |
| 242 ASSERT(window->frame()->host() == &m_frameHost); |
226 } | 243 } |
227 } | 244 } |
228 } | 245 } |
229 #endif // ASSERT_ENABLED | 246 #endif // ASSERT_ENABLED |
230 } | 247 } |
231 | 248 |
232 } // namespace WebCore | 249 } // namespace WebCore |
OLD | NEW |