| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008, The Android Open Source Project | 2 * Copyright 2008, The Android Open Source Project |
| 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. | 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above copyright | 10 * * Redistributions in binary form must reproduce the above copyright |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "core/events/TouchEvent.h" | 27 #include "core/events/TouchEvent.h" |
| 28 | 28 |
| 29 #include "bindings/core/v8/DOMWrapperWorld.h" | 29 #include "bindings/core/v8/DOMWrapperWorld.h" |
| 30 #include "bindings/core/v8/ScriptState.h" | 30 #include "bindings/core/v8/ScriptState.h" |
| 31 #include "core/events/EventDispatcher.h" | 31 #include "core/events/EventDispatcher.h" |
| 32 #include "core/frame/FrameConsole.h" | 32 #include "core/frame/FrameConsole.h" |
| 33 #include "core/frame/FrameView.h" |
| 33 #include "core/frame/LocalDOMWindow.h" | 34 #include "core/frame/LocalDOMWindow.h" |
| 34 #include "core/inspector/ConsoleMessage.h" | 35 #include "core/inspector/ConsoleMessage.h" |
| 36 #include "platform/Histogram.h" |
| 35 | 37 |
| 36 namespace blink { | 38 namespace blink { |
| 37 | 39 |
| 40 namespace { |
| 41 |
| 42 // These offsets change indicies into the ListenerHistogram |
| 43 // enumeration. The addition of a series of offsets then |
| 44 // produces the resulting ListenerHistogram value. |
| 45 // TODO(dtapuska): Remove all of these histogram counts once |
| 46 // https://crbug.com/599609 is fixed. |
| 47 const size_t kTouchTargetHistogramRootScrollerOffset = 6; |
| 48 const size_t kTouchTargetHistogramScrollableDocumentOffset = 3; |
| 49 const size_t kTouchTargetHistogramAlreadyHandledOffset = 0; |
| 50 const size_t kTouchTargetHistogramNotHandledOffset = 1; |
| 51 const size_t kTouchTargetHistogramHandledOffset = 2; |
| 52 const size_t kCapturingOffset = 0; |
| 53 const size_t kAtTargetOffset = 12; |
| 54 const size_t kBubblingOffset = 24; |
| 55 |
| 56 enum TouchTargetAndDispatchResultType { |
| 57 // The following enums represent state captured during the CAPTURING_PHASE. |
| 58 CapturingNonRootScrollerNonScrollableAlreadyHandled, // Non-root-scroller, n
on-scrollable document, already handled. |
| 59 CapturingNonRootScrollerNonScrollableNotHandled, // Non-root-scroller, non-s
crollable document, not handled. |
| 60 CapturingNonRootScrollerNonScrollableHandled, // Non-root-scroller, non-scro
llable document, handled application. |
| 61 CapturingNonRootScrollerScrollableDocumentAlreadyHandled, // Non-root-scroll
er, scrollable document, already handled. |
| 62 CapturingNonRootScrollerScrollableDocumentNotHandled, // Non-root-scroller,
scrollable document, not handled. |
| 63 CapturingNonRootScrollerScrollableDocumentHandled, // Non-root-scroller, scr
ollable document, handled application. |
| 64 CapturingRootScrollerNonScrollableAlreadyHandled, // Root-scroller, non-scro
llable document, already handled. |
| 65 CapturingRootScrollerNonScrollableNotHandled, // Root-scroller, non-scrollab
le document, not handled. |
| 66 CapturingRootScrollerNonScrollableHandled, // Root-scroller, non-scrollable
document, handled. |
| 67 CapturingRootScrollerScrollableDocumentAlreadyHandled, // Root-scroller, scr
ollable document, already handled. |
| 68 CapturingRootScrollerScrollableDocumentNotHandled, // Root-scroller, scrolla
ble document, not handled. |
| 69 CapturingRootScrollerScrollableDocumentHandled, // Root-scroller, scrollable
document, handled. |
| 70 |
| 71 // The following enums represent state captured during the AT_TARGET phase. |
| 72 NonRootScrollerNonScrollableAlreadyHandled, // Non-root-scroller, non-scroll
able document, already handled. |
| 73 NonRootScrollerNonScrollableNotHandled, // Non-root-scroller, non-scrollable
document, not handled. |
| 74 NonRootScrollerNonScrollableHandled, // Non-root-scroller, non-scrollable do
cument, handled application. |
| 75 NonRootScrollerScrollableDocumentAlreadyHandled, // Non-root-scroller, scrol
lable document, already handled. |
| 76 NonRootScrollerScrollableDocumentNotHandled, // Non-root-scroller, scrollabl
e document, not handled. |
| 77 NonRootScrollerScrollableDocumentHandled, // Non-root-scroller, scrollable d
ocument, handled application. |
| 78 RootScrollerNonScrollableAlreadyHandled, // Root-scroller, non-scrollable do
cument, already handled. |
| 79 RootScrollerNonScrollableNotHandled, // Root-scroller, non-scrollable docume
nt, not handled. |
| 80 RootScrollerNonScrollableHandled, // Root-scroller, non-scrollable document,
handled. |
| 81 RootScrollerScrollableDocumentAlreadyHandled, // Root-scroller, scrollable d
ocument, already handled. |
| 82 RootScrollerScrollableDocumentNotHandled, // Root-scroller, scrollable docum
ent, not handled. |
| 83 RootScrollerScrollableDocumentHandled, // Root-scroller, scrollable document
, handled. |
| 84 |
| 85 // The following enums represent state captured during the BUBBLING_PHASE. |
| 86 BubblingNonRootScrollerNonScrollableAlreadyHandled, // Non-root-scroller, no
n-scrollable document, already handled. |
| 87 BubblingNonRootScrollerNonScrollableNotHandled, // Non-root-scroller, non-sc
rollable document, not handled. |
| 88 BubblingNonRootScrollerNonScrollableHandled, // Non-root-scroller, non-scrol
lable document, handled application. |
| 89 BubblingNonRootScrollerScrollableDocumentAlreadyHandled, // Non-root-scrolle
r, scrollable document, already handled. |
| 90 BubblingNonRootScrollerScrollableDocumentNotHandled, // Non-root-scroller, s
crollable document, not handled. |
| 91 BubblingNonRootScrollerScrollableDocumentHandled, // Non-root-scroller, scro
llable document, handled application. |
| 92 BubblingRootScrollerNonScrollableAlreadyHandled, // Root-scroller, non-scrol
lable document, already handled. |
| 93 BubblingRootScrollerNonScrollableNotHandled, // Root-scroller, non-scrollabl
e document, not handled. |
| 94 BubblingRootScrollerNonScrollableHandled, // Root-scroller, non-scrollable d
ocument, handled. |
| 95 BubblingRootScrollerScrollableDocumentAlreadyHandled, // Root-scroller, scro
llable document, already handled. |
| 96 BubblingRootScrollerScrollableDocumentNotHandled, // Root-scroller, scrollab
le document, not handled. |
| 97 BubblingRootScrollerScrollableDocumentHandled, // Root-scroller, scrollable
document, handled. |
| 98 TouchTargetAndDispatchResultTypeMax, |
| 99 }; |
| 100 |
| 101 void logTouchTargetHistogram(EventTarget* eventTarget, unsigned short phase, boo
l defaultPreventedBeforeCurrentTarget, bool defaultPrevented) |
| 102 { |
| 103 int result = 0; |
| 104 Document* document = nullptr; |
| 105 |
| 106 switch (phase) { |
| 107 default: |
| 108 case Event::NONE: |
| 109 return; |
| 110 case Event::CAPTURING_PHASE: |
| 111 result += kCapturingOffset; |
| 112 break; |
| 113 case Event::AT_TARGET: |
| 114 result += kAtTargetOffset; |
| 115 break; |
| 116 case Event::BUBBLING_PHASE: |
| 117 result += kBubblingOffset; |
| 118 break; |
| 119 } |
| 120 |
| 121 if (const LocalDOMWindow* domWindow = eventTarget->toLocalDOMWindow()) { |
| 122 // Treat the window as a root scroller as well. |
| 123 document = domWindow->document(); |
| 124 result += kTouchTargetHistogramRootScrollerOffset; |
| 125 } else if (Node* node = eventTarget->toNode()) { |
| 126 // Report if the target node is the document or body. |
| 127 if (node->isDocumentNode() || node->document().documentElement() == node
|| node->document().body() == node) { |
| 128 result += kTouchTargetHistogramRootScrollerOffset; |
| 129 } |
| 130 document = &node->document(); |
| 131 } |
| 132 |
| 133 if (document) { |
| 134 FrameView* view = document->view(); |
| 135 if (view && view->isScrollable()) |
| 136 result += kTouchTargetHistogramScrollableDocumentOffset; |
| 137 } |
| 138 |
| 139 if (defaultPreventedBeforeCurrentTarget) |
| 140 result += kTouchTargetHistogramAlreadyHandledOffset; |
| 141 else if (defaultPrevented) |
| 142 result += kTouchTargetHistogramHandledOffset; |
| 143 else |
| 144 result += kTouchTargetHistogramNotHandledOffset; |
| 145 |
| 146 DEFINE_STATIC_LOCAL(EnumerationHistogram, rootDocumentListenerHistogram, ("E
vent.Touch.TargetAndDispatchResult2", TouchTargetAndDispatchResultTypeMax)); |
| 147 rootDocumentListenerHistogram.count(static_cast<TouchTargetAndDispatchResult
Type>(result)); |
| 148 } |
| 149 |
| 150 } // namespace |
| 151 |
| 38 TouchEvent::TouchEvent() | 152 TouchEvent::TouchEvent() |
| 153 : m_causesScrollingIfUncanceled(false) |
| 154 , m_firstTouchMoveOrStart(false) |
| 155 , m_defaultPreventedBeforeCurrentTarget(false) |
| 39 { | 156 { |
| 40 } | 157 } |
| 41 | 158 |
| 42 TouchEvent::TouchEvent(TouchList* touches, TouchList* targetTouches, | 159 TouchEvent::TouchEvent(TouchList* touches, TouchList* targetTouches, |
| 43 TouchList* changedTouches, const AtomicString& type, | 160 TouchList* changedTouches, const AtomicString& type, |
| 44 AbstractView* view, | 161 AbstractView* view, |
| 45 PlatformEvent::Modifiers modifiers, bool cancelable, bool causesScrollingIfU
ncanceled, | 162 PlatformEvent::Modifiers modifiers, bool cancelable, bool causesScrollingIfU
ncanceled, bool firstTouchMoveOrStart, |
| 46 double platformTimeStamp) | 163 double platformTimeStamp) |
| 47 // Pass a sourceCapabilities including the ability to fire touchevents when
creating this touchevent, which is always created from input device capabilities
from EventHandler. | 164 // Pass a sourceCapabilities including the ability to fire touchevents when
creating this touchevent, which is always created from input device capabilities
from EventHandler. |
| 48 : UIEventWithKeyState(type, true, cancelable, view, 0, modifiers, platformTi
meStamp, InputDeviceCapabilities::firesTouchEventsSourceCapabilities()), | 165 : UIEventWithKeyState(type, true, cancelable, view, 0, modifiers, platformTi
meStamp, InputDeviceCapabilities::firesTouchEventsSourceCapabilities()), |
| 49 m_touches(touches), m_targetTouches(targetTouches), m_changedTouches(changed
Touches), m_causesScrollingIfUncanceled(causesScrollingIfUncanceled) | 166 m_touches(touches), |
| 167 m_targetTouches(targetTouches), |
| 168 m_changedTouches(changedTouches), |
| 169 m_causesScrollingIfUncanceled(causesScrollingIfUncanceled), |
| 170 m_firstTouchMoveOrStart(firstTouchMoveOrStart), |
| 171 m_defaultPreventedBeforeCurrentTarget(false) |
| 50 { | 172 { |
| 51 } | 173 } |
| 52 | 174 |
| 53 TouchEvent::TouchEvent(const AtomicString& type, const TouchEventInit& initializ
er) | 175 TouchEvent::TouchEvent(const AtomicString& type, const TouchEventInit& initializ
er) |
| 54 : UIEventWithKeyState(type, initializer) | 176 : UIEventWithKeyState(type, initializer) |
| 55 , m_touches(TouchList::create(initializer.touches())) | 177 , m_touches(TouchList::create(initializer.touches())) |
| 56 , m_targetTouches(TouchList::create(initializer.targetTouches())) | 178 , m_targetTouches(TouchList::create(initializer.targetTouches())) |
| 57 , m_changedTouches(TouchList::create(initializer.changedTouches())) | 179 , m_changedTouches(TouchList::create(initializer.changedTouches())) |
| 180 , m_causesScrollingIfUncanceled(false) |
| 181 , m_firstTouchMoveOrStart(false) |
| 182 , m_defaultPreventedBeforeCurrentTarget(false) |
| 58 { | 183 { |
| 59 } | 184 } |
| 60 | 185 |
| 61 TouchEvent::~TouchEvent() | 186 TouchEvent::~TouchEvent() |
| 62 { | 187 { |
| 63 } | 188 } |
| 64 | 189 |
| 65 void TouchEvent::initTouchEvent(ScriptState* scriptState, TouchList* touches, To
uchList* targetTouches, | 190 void TouchEvent::initTouchEvent(ScriptState* scriptState, TouchList* touches, To
uchList* targetTouches, |
| 66 TouchList* changedTouches, const AtomicString& type, | 191 TouchList* changedTouches, const AtomicString& type, |
| 67 AbstractView* view, | 192 AbstractView* view, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 227 |
| 103 // A common developer error is to wait too long before attempting to stop | 228 // A common developer error is to wait too long before attempting to stop |
| 104 // scrolling by consuming a touchmove event. Generate a warning if this | 229 // scrolling by consuming a touchmove event. Generate a warning if this |
| 105 // event is uncancelable. | 230 // event is uncancelable. |
| 106 if (!cancelable() && view() && view()->isLocalDOMWindow() && view()->frame()
) { | 231 if (!cancelable() && view() && view()->isLocalDOMWindow() && view()->frame()
) { |
| 107 toLocalDOMWindow(view())->frame()->console().addMessage(ConsoleMessage::
create(JSMessageSource, WarningMessageLevel, | 232 toLocalDOMWindow(view())->frame()->console().addMessage(ConsoleMessage::
create(JSMessageSource, WarningMessageLevel, |
| 108 "Ignored attempt to cancel a " + type() + " event with cancelable=fa
lse, for example because scrolling is in progress and cannot be interrupted.")); | 233 "Ignored attempt to cancel a " + type() + " event with cancelable=fa
lse, for example because scrolling is in progress and cannot be interrupted.")); |
| 109 } | 234 } |
| 110 } | 235 } |
| 111 | 236 |
| 237 void TouchEvent::doneDispatchingEventAtCurrentTarget() |
| 238 { |
| 239 // Do not log for non-cancelable events, events that don't block |
| 240 // scrolling, have more than one touch point or aren't on the main frame. |
| 241 if (!cancelable() || !m_firstTouchMoveOrStart || !(m_touches && m_touches->l
ength() == 1) || !(view() && view()->frame() && view()->frame()->isMainFrame())) |
| 242 return; |
| 243 |
| 244 bool canceled = defaultPrevented(); |
| 245 logTouchTargetHistogram(currentTarget(), eventPhase(), m_defaultPreventedBef
oreCurrentTarget, canceled); |
| 246 m_defaultPreventedBeforeCurrentTarget = canceled; |
| 247 } |
| 248 |
| 112 EventDispatchMediator* TouchEvent::createMediator() | 249 EventDispatchMediator* TouchEvent::createMediator() |
| 113 { | 250 { |
| 114 return TouchEventDispatchMediator::create(this); | 251 return TouchEventDispatchMediator::create(this); |
| 115 } | 252 } |
| 116 | 253 |
| 117 DEFINE_TRACE(TouchEvent) | 254 DEFINE_TRACE(TouchEvent) |
| 118 { | 255 { |
| 119 visitor->trace(m_touches); | 256 visitor->trace(m_touches); |
| 120 visitor->trace(m_targetTouches); | 257 visitor->trace(m_targetTouches); |
| 121 visitor->trace(m_changedTouches); | 258 visitor->trace(m_changedTouches); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 137 return toTouchEvent(EventDispatchMediator::event()); | 274 return toTouchEvent(EventDispatchMediator::event()); |
| 138 } | 275 } |
| 139 | 276 |
| 140 DispatchEventResult TouchEventDispatchMediator::dispatchEvent(EventDispatcher& d
ispatcher) const | 277 DispatchEventResult TouchEventDispatchMediator::dispatchEvent(EventDispatcher& d
ispatcher) const |
| 141 { | 278 { |
| 142 event().eventPath().adjustForTouchEvent(event()); | 279 event().eventPath().adjustForTouchEvent(event()); |
| 143 return dispatcher.dispatch(); | 280 return dispatcher.dispatch(); |
| 144 } | 281 } |
| 145 | 282 |
| 146 } // namespace blink | 283 } // namespace blink |
| OLD | NEW |