| 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 "core/frame/EventHandlerRegistry.h" | 5 #include "core/frame/EventHandlerRegistry.h" |
| 6 | 6 |
| 7 #include "core/events/EventListenerOptions.h" | 7 #include "core/events/EventListenerOptions.h" |
| 8 #include "core/events/EventUtil.h" | 8 #include "core/events/EventUtil.h" |
| 9 #include "core/frame/LocalDOMWindow.h" | 9 #include "core/frame/LocalDOMWindow.h" |
| 10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
| 11 #include "core/html/HTMLFrameOwnerElement.h" | 11 #include "core/html/HTMLFrameOwnerElement.h" |
| 12 #include "core/page/ChromeClient.h" | 12 #include "core/page/ChromeClient.h" |
| 13 #include "core/page/Page.h" |
| 13 #include "core/page/scrolling/ScrollingCoordinator.h" | 14 #include "core/page/scrolling/ScrollingCoordinator.h" |
| 14 | 15 |
| 15 namespace blink { | 16 namespace blink { |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 WebEventListenerProperties webEventListenerProperties(bool hasBlocking, | 20 WebEventListenerProperties webEventListenerProperties(bool hasBlocking, |
| 20 bool hasPassive) { | 21 bool hasPassive) { |
| 21 if (hasBlocking && hasPassive) | 22 if (hasBlocking && hasPassive) |
| 22 return WebEventListenerProperties::BlockingAndPassive; | 23 return WebEventListenerProperties::BlockingAndPassive; |
| 23 if (hasBlocking) | 24 if (hasBlocking) |
| 24 return WebEventListenerProperties::Blocking; | 25 return WebEventListenerProperties::Blocking; |
| 25 if (hasPassive) | 26 if (hasPassive) |
| 26 return WebEventListenerProperties::Passive; | 27 return WebEventListenerProperties::Passive; |
| 27 return WebEventListenerProperties::Nothing; | 28 return WebEventListenerProperties::Nothing; |
| 28 } | 29 } |
| 29 | 30 |
| 30 } // namespace | 31 } // namespace |
| 31 | 32 |
| 32 EventHandlerRegistry::EventHandlerRegistry(Page& page) : m_page(&page) {} | 33 EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost) |
| 34 : m_frameHost(&frameHost) {} |
| 33 | 35 |
| 34 EventHandlerRegistry::~EventHandlerRegistry() { | 36 EventHandlerRegistry::~EventHandlerRegistry() { |
| 35 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 37 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
| 36 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 38 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
| 37 checkConsistency(handlerClass); | 39 checkConsistency(handlerClass); |
| 38 } | 40 } |
| 39 } | 41 } |
| 40 | 42 |
| 41 bool EventHandlerRegistry::eventTypeToClass( | 43 bool EventHandlerRegistry::eventTypeToClass( |
| 42 const AtomicString& eventType, | 44 const AtomicString& eventType, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 EventHandlerClass handlerClass) { | 168 EventHandlerClass handlerClass) { |
| 167 updateEventHandlerInternal(Add, handlerClass, &target); | 169 updateEventHandlerInternal(Add, handlerClass, &target); |
| 168 } | 170 } |
| 169 | 171 |
| 170 void EventHandlerRegistry::didRemoveEventHandler( | 172 void EventHandlerRegistry::didRemoveEventHandler( |
| 171 EventTarget& target, | 173 EventTarget& target, |
| 172 EventHandlerClass handlerClass) { | 174 EventHandlerClass handlerClass) { |
| 173 updateEventHandlerInternal(Remove, handlerClass, &target); | 175 updateEventHandlerInternal(Remove, handlerClass, &target); |
| 174 } | 176 } |
| 175 | 177 |
| 176 void EventHandlerRegistry::didMoveIntoPage(EventTarget& target) { | 178 void EventHandlerRegistry::didMoveIntoFrameHost(EventTarget& target) { |
| 177 if (!target.hasEventListeners()) | 179 if (!target.hasEventListeners()) |
| 178 return; | 180 return; |
| 179 | 181 |
| 180 // This code is not efficient at all. | 182 // This code is not efficient at all. |
| 181 Vector<AtomicString> eventTypes = target.eventTypes(); | 183 Vector<AtomicString> eventTypes = target.eventTypes(); |
| 182 for (size_t i = 0; i < eventTypes.size(); ++i) { | 184 for (size_t i = 0; i < eventTypes.size(); ++i) { |
| 183 EventListenerVector* listeners = target.getEventListeners(eventTypes[i]); | 185 EventListenerVector* listeners = target.getEventListeners(eventTypes[i]); |
| 184 if (!listeners) | 186 if (!listeners) |
| 185 continue; | 187 continue; |
| 186 for (unsigned count = listeners->size(); count > 0; --count) { | 188 for (unsigned count = listeners->size(); count > 0; --count) { |
| 187 EventHandlerClass handlerClass; | 189 EventHandlerClass handlerClass; |
| 188 if (!eventTypeToClass(eventTypes[i], (*listeners)[count - 1].options(), | 190 if (!eventTypeToClass(eventTypes[i], (*listeners)[count - 1].options(), |
| 189 &handlerClass)) | 191 &handlerClass)) |
| 190 continue; | 192 continue; |
| 191 | 193 |
| 192 didAddEventHandler(target, handlerClass); | 194 didAddEventHandler(target, handlerClass); |
| 193 } | 195 } |
| 194 } | 196 } |
| 195 } | 197 } |
| 196 | 198 |
| 197 void EventHandlerRegistry::didMoveOutOfPage(EventTarget& target) { | 199 void EventHandlerRegistry::didMoveOutOfFrameHost(EventTarget& target) { |
| 198 didRemoveAllEventHandlers(target); | 200 didRemoveAllEventHandlers(target); |
| 199 } | 201 } |
| 200 | 202 |
| 201 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target) { | 203 void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target) { |
| 202 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 204 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
| 203 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 205 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
| 204 updateEventHandlerInternal(RemoveAll, handlerClass, &target); | 206 updateEventHandlerInternal(RemoveAll, handlerClass, &target); |
| 205 } | 207 } |
| 206 } | 208 } |
| 207 | 209 |
| 208 void EventHandlerRegistry::notifyHasHandlersChanged( | 210 void EventHandlerRegistry::notifyHasHandlersChanged( |
| 209 LocalFrame* frame, | 211 LocalFrame* frame, |
| 210 EventHandlerClass handlerClass, | 212 EventHandlerClass handlerClass, |
| 211 bool hasActiveHandlers) { | 213 bool hasActiveHandlers) { |
| 212 switch (handlerClass) { | 214 switch (handlerClass) { |
| 213 case ScrollEvent: | 215 case ScrollEvent: |
| 214 m_page->chromeClient().setHasScrollEventHandlers(frame, | 216 m_frameHost->page().chromeClient().setHasScrollEventHandlers( |
| 215 hasActiveHandlers); | 217 frame, hasActiveHandlers); |
| 216 break; | 218 break; |
| 217 case WheelEventBlocking: | 219 case WheelEventBlocking: |
| 218 case WheelEventPassive: | 220 case WheelEventPassive: |
| 219 m_page->chromeClient().setEventListenerProperties( | 221 m_frameHost->page().chromeClient().setEventListenerProperties( |
| 220 frame, WebEventListenerClass::MouseWheel, | 222 frame, WebEventListenerClass::MouseWheel, |
| 221 webEventListenerProperties(hasEventHandlers(WheelEventBlocking), | 223 webEventListenerProperties(hasEventHandlers(WheelEventBlocking), |
| 222 hasEventHandlers(WheelEventPassive))); | 224 hasEventHandlers(WheelEventPassive))); |
| 223 break; | 225 break; |
| 224 case TouchStartOrMoveEventBlocking: | 226 case TouchStartOrMoveEventBlocking: |
| 225 case TouchStartOrMoveEventPassive: | 227 case TouchStartOrMoveEventPassive: |
| 226 m_page->chromeClient().setEventListenerProperties( | 228 m_frameHost->page().chromeClient().setEventListenerProperties( |
| 227 frame, WebEventListenerClass::TouchStartOrMove, | 229 frame, WebEventListenerClass::TouchStartOrMove, |
| 228 webEventListenerProperties( | 230 webEventListenerProperties( |
| 229 hasEventHandlers(TouchStartOrMoveEventBlocking), | 231 hasEventHandlers(TouchStartOrMoveEventBlocking), |
| 230 hasEventHandlers(TouchStartOrMoveEventPassive))); | 232 hasEventHandlers(TouchStartOrMoveEventPassive))); |
| 231 break; | 233 break; |
| 232 case TouchEndOrCancelEventBlocking: | 234 case TouchEndOrCancelEventBlocking: |
| 233 case TouchEndOrCancelEventPassive: | 235 case TouchEndOrCancelEventPassive: |
| 234 m_page->chromeClient().setEventListenerProperties( | 236 m_frameHost->page().chromeClient().setEventListenerProperties( |
| 235 frame, WebEventListenerClass::TouchEndOrCancel, | 237 frame, WebEventListenerClass::TouchEndOrCancel, |
| 236 webEventListenerProperties( | 238 webEventListenerProperties( |
| 237 hasEventHandlers(TouchEndOrCancelEventBlocking), | 239 hasEventHandlers(TouchEndOrCancelEventBlocking), |
| 238 hasEventHandlers(TouchEndOrCancelEventPassive))); | 240 hasEventHandlers(TouchEndOrCancelEventPassive))); |
| 239 break; | 241 break; |
| 240 #if DCHECK_IS_ON() | 242 #if DCHECK_IS_ON() |
| 241 case EventsForTesting: | 243 case EventsForTesting: |
| 242 break; | 244 break; |
| 243 #endif | 245 #endif |
| 244 default: | 246 default: |
| 245 ASSERT_NOT_REACHED(); | 247 ASSERT_NOT_REACHED(); |
| 246 break; | 248 break; |
| 247 } | 249 } |
| 248 } | 250 } |
| 249 | 251 |
| 250 void EventHandlerRegistry::notifyDidAddOrRemoveEventHandlerTarget( | 252 void EventHandlerRegistry::notifyDidAddOrRemoveEventHandlerTarget( |
| 251 EventHandlerClass handlerClass) { | 253 EventHandlerClass handlerClass) { |
| 252 ScrollingCoordinator* scrollingCoordinator = m_page->scrollingCoordinator(); | 254 ScrollingCoordinator* scrollingCoordinator = |
| 255 m_frameHost->page().scrollingCoordinator(); |
| 253 if (scrollingCoordinator && handlerClass == TouchStartOrMoveEventBlocking) | 256 if (scrollingCoordinator && handlerClass == TouchStartOrMoveEventBlocking) |
| 254 scrollingCoordinator->touchEventTargetRectsDidChange(); | 257 scrollingCoordinator->touchEventTargetRectsDidChange(); |
| 255 } | 258 } |
| 256 | 259 |
| 257 DEFINE_TRACE(EventHandlerRegistry) { | 260 DEFINE_TRACE(EventHandlerRegistry) { |
| 258 visitor->trace(m_page); | 261 visitor->trace(m_frameHost); |
| 259 visitor->template registerWeakMembers< | 262 visitor->template registerWeakMembers< |
| 260 EventHandlerRegistry, &EventHandlerRegistry::clearWeakMembers>(this); | 263 EventHandlerRegistry, &EventHandlerRegistry::clearWeakMembers>(this); |
| 261 } | 264 } |
| 262 | 265 |
| 263 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) { | 266 void EventHandlerRegistry::clearWeakMembers(Visitor* visitor) { |
| 264 Vector<UntracedMember<EventTarget>> deadTargets; | 267 Vector<UntracedMember<EventTarget>> deadTargets; |
| 265 for (size_t i = 0; i < EventHandlerClassCount; ++i) { | 268 for (size_t i = 0; i < EventHandlerClassCount; ++i) { |
| 266 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); | 269 EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i); |
| 267 const EventTargetSet* targets = &m_targets[handlerClass]; | 270 const EventTargetSet* targets = &m_targets[handlerClass]; |
| 268 for (const auto& eventTarget : *targets) { | 271 for (const auto& eventTarget : *targets) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 } | 312 } |
| 310 | 313 |
| 311 void EventHandlerRegistry::checkConsistency( | 314 void EventHandlerRegistry::checkConsistency( |
| 312 EventHandlerClass handlerClass) const { | 315 EventHandlerClass handlerClass) const { |
| 313 #if DCHECK_IS_ON() | 316 #if DCHECK_IS_ON() |
| 314 const EventTargetSet* targets = &m_targets[handlerClass]; | 317 const EventTargetSet* targets = &m_targets[handlerClass]; |
| 315 for (const auto& eventTarget : *targets) { | 318 for (const auto& eventTarget : *targets) { |
| 316 if (Node* node = eventTarget.key->toNode()) { | 319 if (Node* node = eventTarget.key->toNode()) { |
| 317 // See the comment for |documentDetached| if either of these assertions | 320 // See the comment for |documentDetached| if either of these assertions |
| 318 // fails. | 321 // fails. |
| 319 DCHECK(node->document().page()); | 322 DCHECK(node->document().frameHost()); |
| 320 DCHECK(node->document().page() == m_page); | 323 DCHECK(node->document().frameHost() == m_frameHost); |
| 321 } else if (LocalDOMWindow* window = eventTarget.key->toLocalDOMWindow()) { | 324 } else if (LocalDOMWindow* window = eventTarget.key->toLocalDOMWindow()) { |
| 322 // If any of these assertions fail, LocalDOMWindow failed to unregister | 325 // If any of these assertions fail, LocalDOMWindow failed to unregister |
| 323 // its handlers properly. | 326 // its handlers properly. |
| 324 DCHECK(window->frame()); | 327 DCHECK(window->frame()); |
| 325 DCHECK(window->frame()->page()); | 328 DCHECK(window->frame()->host()); |
| 326 DCHECK(window->frame()->page() == m_page); | 329 DCHECK(window->frame()->host() == m_frameHost); |
| 327 } | 330 } |
| 328 } | 331 } |
| 329 #endif // DCHECK_IS_ON() | 332 #endif // DCHECK_IS_ON() |
| 330 } | 333 } |
| 331 | 334 |
| 332 } // namespace blink | 335 } // namespace blink |
| OLD | NEW |