Chromium Code Reviews| 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 |