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