Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: Source/core/page/EventHandler.cpp

Issue 50433002: Fix dragging text inside a input element nested in a draggable element. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Some layout tests Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW
« Source/core/page/DragController.cpp ('K') | « Source/core/page/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698