OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. |
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
128 // need to ensure here is that the scale isn't so small that integer overflow ca n occur when | 128 // need to ensure here is that the scale isn't so small that integer overflow ca n occur when |
129 // dividing cursor sizes (limited above) by the scale. | 129 // dividing cursor sizes (limited above) by the scale. |
130 static const double minimumCursorScale = 0.001; | 130 static const double minimumCursorScale = 0.001; |
131 | 131 |
132 #if OS(MACOSX) | 132 #if OS(MACOSX) |
133 static const double TextDragDelay = 0.15; | 133 static const double TextDragDelay = 0.15; |
134 #else | 134 #else |
135 static const double TextDragDelay = 0.0; | 135 static const double TextDragDelay = 0.0; |
136 #endif | 136 #endif |
137 | 137 |
138 | |
139 enum NoCursorChangeType { NoCursorChange }; | 138 enum NoCursorChangeType { NoCursorChange }; |
140 | 139 |
141 class OptionalCursor { | 140 class OptionalCursor { |
142 public: | 141 public: |
143 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { } | 142 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { } |
144 OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(curs or) { } | 143 OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(curs or) { } |
145 | 144 |
146 bool isCursorChange() const { return m_isCursorChange; } | 145 bool isCursorChange() const { return m_isCursorChange; } |
147 const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; } | 146 const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; } |
148 | 147 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 return true; | 277 return true; |
279 return targetNode->isShadowRoot() && toShadowRoot(targetNode)->host()->hasTa gName(inputTag); | 278 return targetNode->isShadowRoot() && toShadowRoot(targetNode)->host()->hasTa gName(inputTag); |
280 } | 279 } |
281 | 280 |
282 EventHandler::EventHandler(Frame* frame) | 281 EventHandler::EventHandler(Frame* frame) |
283 : m_frame(frame) | 282 : m_frame(frame) |
284 , m_mousePressed(false) | 283 , m_mousePressed(false) |
285 , m_capturesDragging(false) | 284 , m_capturesDragging(false) |
286 , m_mouseDownMayStartSelect(false) | 285 , m_mouseDownMayStartSelect(false) |
287 , m_mouseDownMayStartDrag(false) | 286 , m_mouseDownMayStartDrag(false) |
288 , m_dragMayStartSelectionInstead(false) | |
289 , m_mouseDownWasSingleClickInSelection(false) | 287 , m_mouseDownWasSingleClickInSelection(false) |
290 , m_selectionInitiationState(HaveNotStartedSelection) | 288 , m_selectionInitiationState(HaveNotStartedSelection) |
291 , m_panScrollButtonPressed(false) | 289 , m_panScrollButtonPressed(false) |
292 , m_hoverTimer(this, &EventHandler::hoverTimerFired) | 290 , m_hoverTimer(this, &EventHandler::hoverTimerFired) |
293 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) | 291 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) |
294 , m_mouseDownMayStartAutoscroll(false) | 292 , m_mouseDownMayStartAutoscroll(false) |
295 , m_mouseDownWasInSubframe(false) | 293 , m_mouseDownWasInSubframe(false) |
296 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) | 294 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) |
297 , m_svgPan(false) | 295 , m_svgPan(false) |
298 , m_resizeScrollableArea(0) | 296 , m_resizeScrollableArea(0) |
(...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3212 if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument()) | 3210 if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument()) |
3213 dragState().m_dragSrc = rootEditableElement; | 3211 dragState().m_dragSrc = rootEditableElement; |
3214 } | 3212 } |
3215 | 3213 |
3216 // returns if we should continue "default processing", i.e., whether eventhandle r canceled | 3214 // returns if we should continue "default processing", i.e., whether eventhandle r canceled |
3217 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const Pla tformMouseEvent& event) | 3215 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const Pla tformMouseEvent& event) |
3218 { | 3216 { |
3219 return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dra gState().m_dragClipboard.get()); | 3217 return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dra gState().m_dragClipboard.get()); |
3220 } | 3218 } |
3221 | 3219 |
3222 static bool exactlyOneBitSet(DragSourceAction n) | |
3223 { | |
3224 return n && !(n & (n - 1)); | |
3225 } | |
3226 | |
3227 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr agHysteresis checkDragHysteresis) | 3220 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr agHysteresis checkDragHysteresis) |
3228 { | 3221 { |
3222 ASSERT(event.event().type() == PlatformEvent::MouseMoved); | |
3229 // Callers must protect the reference to FrameView, since this function may dispatch DOM | 3223 // Callers must protect the reference to FrameView, since this function may dispatch DOM |
3230 // events, causing page/FrameView to go away. | 3224 // events, causing page/FrameView to go away. |
3231 ASSERT(m_frame); | 3225 ASSERT(m_frame); |
3232 ASSERT(m_frame->view()); | 3226 ASSERT(m_frame->view()); |
3233 if (!m_frame->page()) | 3227 if (!m_frame->page()) |
3234 return false; | 3228 return false; |
3235 | 3229 |
3236 if (event.event().button() != LeftButton || event.event().type() != Platform Event::MouseMoved) { | 3230 if (event.event().button() != LeftButton || event.event().type() != Platform Event::MouseMoved) { |
3237 // If we allowed the other side of the bridge to handle a drag | 3231 // If we allowed the other side of the bridge to handle a drag |
3238 // last time, then m_mousePressed might still be set. So we | 3232 // last time, then m_mousePressed might still be set. So we |
3239 // clear it now to make sure the next move after a drag | 3233 // clear it now to make sure the next move after a drag |
3240 // doesn't look like a drag. | 3234 // doesn't look like a drag. |
3241 m_mousePressed = false; | 3235 m_mousePressed = false; |
3242 return false; | 3236 return false; |
3243 } | 3237 } |
3244 | 3238 |
3245 if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) { | 3239 if (m_mouseDownMayStartDrag) { |
3246 // try to find an element that wants to be dragged | 3240 HitTestRequest request(HitTestRequest::ReadOnly); |
3247 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Confus ingAndOftenMisusedDisallowShadowContent); | |
3248 HitTestResult result(m_mouseDownPos); | 3241 HitTestResult result(m_mouseDownPos); |
3249 m_frame->contentRenderer()->hitTest(request, result); | 3242 m_frame->contentRenderer()->hitTest(request, result); |
3250 Node* node = result.innerNode(); | 3243 Node* node = result.innerNode(); |
3251 if (node) | 3244 if (node) { |
3252 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, dragState()); | 3245 DragController::SelectionDragPolicy selectionDragPolicy = event.even t().timestamp() - m_mouseDownTimestamp < TextDragDelay |
3253 else | 3246 ? DragController::DisallowSelectionDrag |
3247 : DragController::AllowSelectionDrag; | |
3248 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType); | |
3249 } else { | |
3254 dragState().m_dragSrc = 0; | 3250 dragState().m_dragSrc = 0; |
3251 } | |
3255 | 3252 |
3256 if (!dragState().m_dragSrc) | 3253 if (!dragState().m_dragSrc) |
3257 m_mouseDownMayStartDrag = false; // no element is draggable | 3254 m_mouseDownMayStartDrag = false; // no element is draggable |
3258 else | |
3259 m_dragMayStartSelectionInstead = (dragState().m_dragType & DragSourc eActionSelection); | |
3260 } | |
3261 | |
3262 // For drags starting in the selection, the user must wait between the mouse down and mousedrag, | |
3263 // or else we bail on the dragging stuff and allow selection to occur | |
3264 if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState( ).m_dragType & DragSourceActionSelection) && event.event().timestamp() - m_mouse DownTimestamp < TextDragDelay) { | |
3265 ASSERT(event.event().type() == PlatformEvent::MouseMoved); | |
3266 if ((dragState().m_dragType & DragSourceActionImage)) { | |
3267 // ... unless the mouse is over an image, then we start dragging jus t the image | |
3268 dragState().m_dragType = DragSourceActionImage; | |
3269 } else if (!(dragState().m_dragType & (DragSourceActionDHTML | DragSourc eActionLink))) { | |
3270 // ... but only bail if we're not over an unselectable element. | |
3271 m_mouseDownMayStartDrag = false; | |
3272 dragState().m_dragSrc = 0; | |
3273 } else { | |
3274 // Prevent the following case from occuring: | |
3275 // 1. User starts a drag immediately after mouse down over an unsele ctable element. | |
3276 // 2. We enter this block and decided that since we're over an unsel ectable element, | |
3277 // don't cancel the drag. | |
3278 // 3. The drag gets resolved as a potential selection drag below /bu t/ we haven't | |
3279 // exceeded the drag hysteresis yet. | |
3280 // 4. We enter this block again, and since it's now marked as a sele ction drag, we | |
3281 // cancel the drag. | |
tony
2013/11/04 18:23:40
Do we have a test for this case?
dcheng
2013/11/12 00:58:17
I recall writing one but couldn't find it after lo
| |
3282 m_dragMayStartSelectionInstead = false; | |
3283 } | |
3284 } | 3255 } |
3285 | 3256 |
3286 if (!m_mouseDownMayStartDrag) | 3257 if (!m_mouseDownMayStartDrag) |
3287 return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll; | 3258 return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll; |
3288 | 3259 |
3289 if (!exactlyOneBitSet(dragState().m_dragType)) { | |
3290 ASSERT((dragState().m_dragType & DragSourceActionSelection)); | |
3291 ASSERT((dragState().m_dragType & ~DragSourceActionSelection) == DragSour ceActionDHTML | |
3292 || (dragState().m_dragType & ~DragSourceActionSelection) == Drag SourceActionImage | |
3293 || (dragState().m_dragType & ~DragSourceActionSelection) == Drag SourceActionLink); | |
3294 dragState().m_dragType = DragSourceActionSelection; | |
3295 } | |
3296 | |
3297 // We are starting a text/image/url drag, so the cursor should be an arrow | 3260 // We are starting a text/image/url drag, so the cursor should be an arrow |
3298 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer). | 3261 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer). |
3299 m_frame->view()->setCursor(pointerCursor()); | 3262 m_frame->view()->setCursor(pointerCursor()); |
3300 | 3263 |
3301 if (checkDragHysteresis == ShouldCheckDragHysteresis && !dragHysteresisExcee ded(event.event().position())) | 3264 if (checkDragHysteresis == ShouldCheckDragHysteresis && !dragHysteresisExcee ded(event.event().position())) |
3302 return true; | 3265 return true; |
3303 | 3266 |
3304 // Once we're past the hysteresis point, we don't want to treat this gesture as a click | 3267 // Once we're past the hysteresis point, we don't want to treat this gesture as a click |
3305 invalidateClick(); | 3268 invalidateClick(); |
3306 | 3269 |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3977 unsigned EventHandler::accessKeyModifiers() | 3940 unsigned EventHandler::accessKeyModifiers() |
3978 { | 3941 { |
3979 #if OS(MACOSX) | 3942 #if OS(MACOSX) |
3980 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; | 3943 return PlatformEvent::CtrlKey | PlatformEvent::AltKey; |
3981 #else | 3944 #else |
3982 return PlatformEvent::AltKey; | 3945 return PlatformEvent::AltKey; |
3983 #endif | 3946 #endif |
3984 } | 3947 } |
3985 | 3948 |
3986 } // namespace WebCore | 3949 } // namespace WebCore |
OLD | NEW |