Commit fd6ff3dc authored by darin@apple.com's avatar darin@apple.com

Use Element instead of Node in DragState, also redo DragState struct

https://bugs.webkit.org/show_bug.cgi?id=116411

Reviewed by Sam Weinig.

The drag source is an element, so use RefPtr<Element> instead of RefPtr<Node>.

Also, the entire drag state is about dragging, so no need for the word "drag" in the
name of its members. Also, it's a struct, so the members don't need m_ prefixes.

* page/DragController.cpp: Removed unneeded include of Node.h since it's included by
Element.h, which is also included.
(WebCore::DragController::draggableElement): Renamed from Node to Element and changed
the types and names of arguments accordingly. Also made this function handle a
startElement of 0 so callers don't need to. Also updated for changes to DragState members.
(WebCore::DragController::startDrag): Updated for changes to DragState members.
Since dragSource can only be an element, was able to get rid of isElementNode checks.

* page/DragController.h: Fixed style of forward declarations of structs. Updated for
change of draggableNode to draggableElement. Also removed declarations of nonexistent
selectionDraggingRect and doDrag functions.

* page/DragState.h: Rewrote practically this whole header. Added an include of Element
instead of Node since that's what we use now. Removed includes that are redundant.
There's no problem copying a DragState, so removed WTF_MAKE_NONCOPYABLE. There's no need
to allocate a DragState on the heap, so removed WTF_MAKE_FAST_ALLOCATED. The event dispatch
boolean is never set to a constant, so there's no need for a policy enum; it can just be
a boolean. Removed the "m_" prefixes from the struct members, since this is a struct with
public members and we don't use the prefix in those cases. Removed the word "drag" from the
struct member names since this entire struct is about dragging and has drag in its name.
Left the comments mostly intact, even though I'm not certain of their value.

* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent): Updated for changes to DragState.
(WebCore::EventHandler::eventMayStartDrag):
Use innerElement instead of innerNode to call draggableElement instead of draggableNode.
(WebCore::EventHandler::updateDragAndDrop): Updated for changes to DragState.
(WebCore::EventHandler::cancelDragAndDrop): Ditto.
(WebCore::EventHandler::handleWheelEvent): Added FIXME.
(WebCore::EventHandler::dragHysteresisExceeded): Updated for changes to DragState.
(WebCore::EventHandler::freeClipboard): Updated for changes to DragState. Also re-added
code to release the clipboard object, which is needed here to avoid keeping it around in
memory until the next drag.
(WebCore::EventHandler::dragSourceEndedAt): Updated for changes to DragState.
(WebCore::EventHandler::updateDragStateAfterEditDragIfNeeded): Ditto.
(WebCore::EventHandler::dispatchDragSrcEvent): Ditto.
(WebCore::EventHandler::handleDrag): Updated for changes to DragState. Use innerElement
instead of innerNode to call draggableElement instead of draggableNode. No longer need to
null check innerElement because draggableElement does that. Removed unneeded else that was
setting m_dragSrc to zero since it's guaranteed to already be zero.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150354 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 247ec59d
2013-05-19 Darin Adler <darin@apple.com>
Use Element instead of Node in DragState, also redo DragState struct
https://bugs.webkit.org/show_bug.cgi?id=116411
Reviewed by Sam Weinig.
The drag source is an element, so use RefPtr<Element> instead of RefPtr<Node>.
Also, the entire drag state is about dragging, so no need for the word "drag" in the
name of its members. Also, it's a struct, so the members don't need m_ prefixes.
* page/DragController.cpp: Removed unneeded include of Node.h since it's included by
Element.h, which is also included.
(WebCore::DragController::draggableElement): Renamed from Node to Element and changed
the types and names of arguments accordingly. Also made this function handle a
startElement of 0 so callers don't need to. Also updated for changes to DragState members.
(WebCore::DragController::startDrag): Updated for changes to DragState members.
Since dragSource can only be an element, was able to get rid of isElementNode checks.
* page/DragController.h: Fixed style of forward declarations of structs. Updated for
change of draggableNode to draggableElement. Also removed declarations of nonexistent
selectionDraggingRect and doDrag functions.
* page/DragState.h: Rewrote practically this whole header. Added an include of Element
instead of Node since that's what we use now. Removed includes that are redundant.
There's no problem copying a DragState, so removed WTF_MAKE_NONCOPYABLE. There's no need
to allocate a DragState on the heap, so removed WTF_MAKE_FAST_ALLOCATED. The event dispatch
boolean is never set to a constant, so there's no need for a policy enum; it can just be
a boolean. Removed the "m_" prefixes from the struct members, since this is a struct with
public members and we don't use the prefix in those cases. Removed the word "drag" from the
struct member names since this entire struct is about dragging and has drag in its name.
Left the comments mostly intact, even though I'm not certain of their value.
* page/EventHandler.cpp:
(WebCore::EventHandler::handleMousePressEvent): Updated for changes to DragState.
(WebCore::EventHandler::eventMayStartDrag):
Use innerElement instead of innerNode to call draggableElement instead of draggableNode.
(WebCore::EventHandler::updateDragAndDrop): Updated for changes to DragState.
(WebCore::EventHandler::cancelDragAndDrop): Ditto.
(WebCore::EventHandler::handleWheelEvent): Added FIXME.
(WebCore::EventHandler::dragHysteresisExceeded): Updated for changes to DragState.
(WebCore::EventHandler::freeClipboard): Updated for changes to DragState. Also re-added
code to release the clipboard object, which is needed here to avoid keeping it around in
memory until the next drag.
(WebCore::EventHandler::dragSourceEndedAt): Updated for changes to DragState.
(WebCore::EventHandler::updateDragStateAfterEditDragIfNeeded): Ditto.
(WebCore::EventHandler::dispatchDragSrcEvent): Ditto.
(WebCore::EventHandler::handleDrag): Updated for changes to DragState. Use innerElement
instead of innerNode to call draggableElement instead of draggableNode. No longer need to
null check innerElement because draggableElement does that. Removed unneeded else that was
setting m_dragSrc to zero since it's guaranteed to already be zero.
2013-05-19 Anders Carlsson <andersca@apple.com>
Remove ChromeClient::webView()
......
/*
* Copyright (C) 2007, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2007, 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -59,7 +59,6 @@
#include "Image.h"
#include "ImageOrientation.h"
#include "MoveSelectionCommand.h"
#include "Node.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PluginDocument.h"
......@@ -635,17 +634,19 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return true;
}
Node* DragController::draggableNode(const Frame* src, Node* startNode, const IntPoint& dragOrigin, DragState& state) const
Element* DragController::draggableElement(const Frame* sourceFrame, Element* startElement, const IntPoint& dragOrigin, DragState& state) const
{
state.m_dragType = (src->selection()->contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
state.type = (sourceFrame->selection()->contains(dragOrigin)) ? DragSourceActionSelection : DragSourceActionNone;
if (!startElement)
return 0;
for (const RenderObject* renderer = startNode->renderer(); renderer; renderer = renderer->parent()) {
for (const RenderObject* renderer = startElement->renderer(); renderer; renderer = renderer->parent()) {
Node* node = renderer->nonPseudoNode();
if (!node)
// Anonymous render blocks don't correspond to actual DOM nodes, so we skip over them
// for the purposes of finding a draggable node.
continue;
if (!(state.m_dragType & DragSourceActionSelection) && node->isTextNode() && node->canStartSelection())
if (!(state.type & DragSourceActionSelection) && node->isTextNode() && node->canStartSelection())
// In this case we have a click in the unselected portion of text. If this text is
// selectable, we want to start the selection process instead of looking for a parent
// to try to drag.
......@@ -653,29 +654,29 @@ Node* DragController::draggableNode(const Frame* src, Node* startNode, const Int
if (node->isElementNode()) {
EUserDrag dragMode = renderer->style()->userDrag();
if ((m_dragSourceAction & DragSourceActionDHTML) && dragMode == DRAG_ELEMENT) {
state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionDHTML);
return node;
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionDHTML);
return toElement(node);
}
if (dragMode == DRAG_AUTO) {
if ((m_dragSourceAction & DragSourceActionImage)
&& node->hasTagName(HTMLNames::imgTag)
&& src->settings()
&& src->settings()->loadsImagesAutomatically()) {
state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionImage);
return node;
&& sourceFrame->settings()
&& sourceFrame->settings()->loadsImagesAutomatically()) {
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionImage);
return toElement(node);
}
if ((m_dragSourceAction & DragSourceActionLink)
&& node->hasTagName(HTMLNames::aTag)
&& static_cast<HTMLAnchorElement*>(node)->isLiveLink()) {
state.m_dragType = static_cast<DragSourceAction>(state.m_dragType | DragSourceActionLink);
return node;
state.type = static_cast<DragSourceAction>(state.type | DragSourceActionLink);
return toElement(node);
}
}
}
}
// We either have nothing to drag or we have a selection and we're not over a draggable element.
return (state.m_dragType & DragSourceActionSelection) ? startNode : 0;
return (state.type & DragSourceActionSelection) ? startElement : 0;
}
static CachedImage* getCachedImage(Element* element)
......@@ -748,7 +749,7 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation
return false;
HitTestResult hitTestResult = src->eventHandler()->hitTestResultAtPoint(dragOrigin, HitTestRequest::ReadOnly | HitTestRequest::Active);
if (!state.m_dragSrc->contains(hitTestResult.innerNode()))
if (!state.source->contains(hitTestResult.innerNode()))
// The original node being dragged isn't under the drag origin anymore... maybe it was
// hidden or moved out from under the cursor. Regardless, we don't want to start a drag on
// something that's not actually under the drag origin.
......@@ -765,10 +766,10 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation
IntPoint dragLoc(0, 0);
IntPoint dragImageOffset(0, 0);
Clipboard* clipboard = state.m_dragClipboard.get();
if (state.m_dragType == DragSourceActionDHTML)
Clipboard* clipboard = state.clipboard.get();
if (state.type == DragSourceActionDHTML)
dragImage = clipboard->createDragImage(dragImageOffset);
if (state.m_dragType == DragSourceActionSelection || !imageURL.isEmpty() || !linkURL.isEmpty())
if (state.type == DragSourceActionSelection || !imageURL.isEmpty() || !linkURL.isEmpty())
// Selection, image, and link drags receive a default set of allowed drag operations that
// follows from:
// http://trac.webkit.org/browser/trunk/WebKit/mac/WebView/WebHTMLView.mm?rev=48526#L3430
......@@ -783,10 +784,10 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation
bool startedDrag = true; // optimism - we almost always manage to start the drag
Node* node = state.m_dragSrc.get();
Element* element = state.source.get();
Image* image = node->isElementNode() ? getImage(toElement(node)) : 0;
if (state.m_dragType == DragSourceActionSelection) {
Image* image = getImage(element);
if (state.type == DragSourceActionSelection) {
if (!clipboard->hasData()) {
if (enclosingTextFormControl(src->selection()->start()))
clipboard->writePlainText(src->editor().selectedTextForClipboard());
......@@ -804,12 +805,11 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation
m_dragOffset = IntPoint(dragOrigin.x() - dragLoc.x(), dragOrigin.y() - dragLoc.y());
}
doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else if (!imageURL.isEmpty() && node && node->isElementNode() && image && !image->isNull()
} else if (!imageURL.isEmpty() && element && image && !image->isNull()
&& (m_dragSourceAction & DragSourceActionImage)) {
// We shouldn't be starting a drag for an image that can't provide an extension.
// This is an early detection for problems encountered later upon drop.
ASSERT(!image->filenameExtension().isEmpty());
Element* element = toElement(node);
if (!clipboard->hasData()) {
m_draggingImageURL = imageURL;
prepareClipboardForImageDrag(src, clipboard, element, linkURL, imageURL, hitTestResult.altDisplayString());
......@@ -849,12 +849,12 @@ bool DragController::startDrag(Frame* src, const DragState& state, DragOperation
dragLoc = IntPoint(mouseDraggedPoint.x() + m_dragOffset.x(), mouseDraggedPoint.y() + m_dragOffset.y());
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (state.m_dragType == DragSourceActionDHTML) {
} else if (state.type == DragSourceActionDHTML) {
ASSERT(m_dragSourceAction & DragSourceActionDHTML);
m_client->willPerformDragSourceAction(DragSourceActionDHTML, dragOrigin, clipboard);
doSystemDrag(dragImage, dragLoc, dragOrigin, clipboard, src, false);
} else {
// draggableNode() determined an image or link node was draggable, but it turns out the
// draggableElement() determined an image or link node was draggable, but it turns out the
// image or link had no URL, so there is nothing to drag.
startedDrag = false;
}
......
......@@ -37,8 +37,6 @@ namespace WebCore {
class Document;
class DragClient;
class DragData;
struct DragSession;
struct DragState;
class Element;
class Frame;
class FrameSelection;
......@@ -49,7 +47,10 @@ namespace WebCore {
class Page;
class PlatformMouseEvent;
class Range;
struct DragSession;
struct DragState;
class DragController {
WTF_MAKE_NONCOPYABLE(DragController); WTF_MAKE_FAST_ALLOCATED;
public:
......@@ -78,7 +79,7 @@ namespace WebCore {
DragDestinationAction dragDestinationAction() const { return m_dragDestinationAction; }
DragSourceAction delegateDragSourceAction(const IntPoint& rootViewPoint);
Node* draggableNode(const Frame*, Node*, const IntPoint&, DragState&) const;
Element* draggableElement(const Frame*, Element* start, const IntPoint&, DragState&) const;
void dragEnded();
void placeDragCaret(const IntPoint&);
......@@ -109,8 +110,6 @@ namespace WebCore {
void mouseMovedIntoDocument(Document*);
IntRect selectionDraggingRect(Frame*);
bool doDrag(Frame* src, Clipboard* clipboard, DragImageRef dragImage, const KURL& linkURL, const KURL& imageURL, Node* node, IntPoint& dragLoc, IntPoint& dragImageOffset);
void doImageDrag(Element*, const IntPoint&, const IntRect&, Clipboard*, Frame*, IntPoint&);
void doSystemDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool forLink);
void cleanupAfterSystemDrag();
......
/*
* Copyright (C) 2011 Google Inc.
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -28,30 +29,15 @@
#include "Clipboard.h"
#include "DragActions.h"
#include "Node.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
#include "Element.h"
namespace WebCore {
class Clipboard;
class Node;
struct DragState {
WTF_MAKE_NONCOPYABLE(DragState);
WTF_MAKE_FAST_ALLOCATED;
public:
enum EventDispatchPolicy {
DoNotDispatchEvents,
DispatchEvents,
};
DragState() { }
bool shouldDispatchEvents() const { return m_eventDispatchPolicy == DispatchEvents; }
RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
EventDispatchPolicy m_eventDispatchPolicy;
DragSourceAction m_dragType;
RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
RefPtr<Element> source; // Element that may be a drag source, for the current mouse gesture.
bool shouldDispatchEvents;
DragSourceAction type;
RefPtr<Clipboard> clipboard; // Used on only the source side of dragging.
};
} // namespace WebCore
......
/*
* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
* Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
*
......@@ -650,7 +650,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
{
#if ENABLE(DRAG_SUPPORT)
// Reset drag state.
dragState().m_dragSrc = 0;
dragState().source = 0;
#endif
cancelFakeMouseMoveEvent();
......@@ -791,7 +791,7 @@ bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
HitTestResult result(view->windowToContents(event.position()));
m_frame->contentRenderer()->hitTest(request, result);
DragState state;
return result.innerNode() && page->dragController()->draggableNode(m_frame, result.innerNode(), result.roundedPointInInnerNodeFrame(), state);
return result.innerElement() && page->dragController()->draggableElement(m_frame, result.innerElement(), result.roundedPointInInnerNodeFrame(), state);
}
void EventHandler::updateSelectionForMouseDrag()
......@@ -2082,7 +2082,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
accept = targetFrame->eventHandler()->updateDragAndDrop(event, clipboard);
} else if (newTarget) {
// As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event.
if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
if (dragState().source && dragState().shouldDispatchEvents) {
// for now we don't care if event handler cancels default behavior, since there is none
dispatchDragSrcEvent(eventNames().dragEvent, event);
}
......@@ -2109,7 +2109,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
accept = targetFrame->eventHandler()->updateDragAndDrop(event, clipboard);
} else if (newTarget) {
// Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
if (!m_shouldOnlyFireDragOverEvent && dragState().source && dragState().shouldDispatchEvents) {
// for now we don't care if event handler cancels default behavior, since there is none
dispatchDragSrcEvent(eventNames().dragEvent, event);
}
......@@ -2131,7 +2131,7 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard*
if (targetFrame)
targetFrame->eventHandler()->cancelDragAndDrop(event, clipboard);
} else if (m_dragTarget.get()) {
if (dragState().m_dragSrc && dragState().shouldDispatchEvents())
if (dragState().source && dragState().shouldDispatchEvents)
dispatchDragSrcEvent(eventNames().dragEvent, event);
dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
}
......@@ -2413,6 +2413,7 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
bool useLatchedWheelEventNode = e.useLatchedEventNode();
// FIXME: Is the following code different from just calling innerElement?
Node* node = result.innerNode();
// Wheel events should not dispatch to text nodes.
if (node && node->isTextNode())
......@@ -3394,7 +3395,7 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
IntSize delta = dragLocation - m_mouseDownPos;
int threshold = GeneralDragHysteresis;
switch (dragState().m_dragType) {
switch (dragState().type) {
case DragSourceActionSelection:
threshold = TextDragHysteresis;
break;
......@@ -3416,8 +3417,10 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
void EventHandler::freeClipboard()
{
if (dragState().m_dragClipboard)
dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
if (!dragState().clipboard)
return;
dragState().clipboard->setAccessPolicy(ClipboardNumb);
dragState().clipboard = 0;
}
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
......@@ -3426,13 +3429,13 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowShadowContent);
prepareMouseEvent(request, event);
if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
dragState().m_dragClipboard->setDestinationOperation(operation);
// for now we don't care if event handler cancels default behavior, since there is none
if (dragState().source && dragState().shouldDispatchEvents) {
dragState().clipboard->setDestinationOperation(operation);
// For now we don't care if event handler cancels default behavior, since there is no default behavior.
dispatchDragSrcEvent(eventNames().dragendEvent, event);
}
freeClipboard();
dragState().m_dragSrc = 0;
dragState().source = 0;
// In case the drag was ended due to an escape key press we need to ensure
// that consecutive mousemove events don't reinitiate the drag and drop.
m_mouseDownMayStartDrag = false;
......@@ -3440,15 +3443,15 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
{
// If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element.
if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument())
dragState().m_dragSrc = rootEditableElement;
// If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editable element.
if (dragState().source && !dragState().source->inDocument())
dragState().source = rootEditableElement;
}
// returns if we should continue "default processing", i.e., whether eventhandler canceled
// Return value indicates if we should continue "default processing", i.e., whether event handler canceled.
bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
{
return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
return !dispatchDragEvent(eventType, dragState().source.get(), event, dragState().clipboard.get());
}
static bool ExactlyOneBitSet(DragSourceAction n)
......@@ -3472,48 +3475,42 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
// Careful that the drag starting logic stays in sync with eventMayStartDrag()
if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
dragState().m_eventDispatchPolicy = (updateDragSourceActionsAllowed() & DragSourceActionDHTML) ? DragState::DispatchEvents: DragState::DoNotDispatchEvents;
if (m_mouseDownMayStartDrag && !dragState().source) {
dragState().shouldDispatchEvents = (updateDragSourceActionsAllowed() & DragSourceActionDHTML);
// try to find an element that wants to be dragged
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
HitTestResult result(m_mouseDownPos);
m_frame->contentRenderer()->hitTest(request, result);
Node* node = result.innerNode();
if (node && m_frame->page())
dragState().m_dragSrc = m_frame->page()->dragController()->draggableNode(m_frame, node, m_mouseDownPos, dragState());
else
dragState().m_dragSrc = 0;
if (m_frame->page())
dragState().source = m_frame->page()->dragController()->draggableElement(m_frame, result.innerElement(), m_mouseDownPos, dragState());
if (!dragState().m_dragSrc)
if (!dragState().source)
m_mouseDownMayStartDrag = false; // no element is draggable
else
m_dragMayStartSelectionInstead = (dragState().m_dragType & DragSourceActionSelection);
m_dragMayStartSelectionInstead = (dragState().type & DragSourceActionSelection);
}
// For drags starting in the selection, the user must wait between the mousedown and mousedrag,
// or else we bail on the dragging stuff and allow selection to occur
if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().m_dragType & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().type & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
ASSERT(event.event().type() == PlatformEvent::MouseMoved);
if ((dragState().m_dragType & DragSourceActionImage)) {
if ((dragState().type & DragSourceActionImage)) {
// ... unless the mouse is over an image, then we start dragging just the image
dragState().m_dragType = DragSourceActionImage;
} else if (!(dragState().m_dragType & (DragSourceActionDHTML | DragSourceActionLink))) {
dragState().type = DragSourceActionImage;
} else if (!(dragState().type & (DragSourceActionDHTML | DragSourceActionLink))) {
// ... but only bail if we're not over an unselectable element.
m_mouseDownMayStartDrag = false;
dragState().m_dragSrc = 0;
dragState().source = 0;
// ... but if this was the first click in the window, we don't even want to start selection
if (eventActivatedView(event.event()))
m_mouseDownMayStartSelect = false;
} else {
// Prevent the following case from occuring:
// 1. User starts a drag immediately after mouse down over an unselectable element.
// 2. We enter this block and decided that since we're over an unselectable element,
// don't cancel the drag.
// 3. The drag gets resolved as a potential selection drag below /but/ we haven't
// exceeded the drag hysteresis yet.
// 4. We enter this block again, and since it's now marked as a selection drag, we
// cancel the drag.
// 2. We enter this block and decided that since we're over an unselectable element, don't cancel the drag.
// 3. The drag gets resolved as a potential selection drag below /but/ we haven't exceeded the drag hysteresis yet.
// 4. We enter this block again, and since it's now marked as a selection drag, we cancel the drag.
m_dragMayStartSelectionInstead = false;
}
}
......@@ -3521,12 +3518,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
if (!m_mouseDownMayStartDrag)
return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
if (!ExactlyOneBitSet(dragState().m_dragType)) {
ASSERT((dragState().m_dragType & DragSourceActionSelection));
ASSERT((dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionDHTML
|| (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionImage
|| (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionLink);
dragState().m_dragType = DragSourceActionSelection;
if (!ExactlyOneBitSet(dragState().type)) {
ASSERT((dragState().type & DragSourceActionSelection));
ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
|| (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
dragState().type = DragSourceActionSelection;
}
// We are starting a text/image/url drag, so the cursor should be an arrow
......@@ -3543,19 +3540,19 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
DragOperation srcOp = DragOperationNone;
freeClipboard(); // would only happen if we missed a dragEnd. Do it anyway, just
// to make sure it gets numbified
dragState().m_dragClipboard = createDraggingClipboard();
// This does work only if we missed a dragEnd. Do it anyway, just to make sure the old clipboard gets numbed.
freeClipboard();
dragState().clipboard = createDraggingClipboard();
if (dragState().shouldDispatchEvents()) {
// Check to see if the is a DOM based drag, if it is get the DOM specified drag
// image and offset
if (dragState().m_dragType == DragSourceActionDHTML) {
if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
if (dragState().shouldDispatchEvents) {
// Check to see if the is a DOM based drag. If it is, get the DOM specified drag image and offset.
if (dragState().type == DragSourceActionDHTML) {
if (RenderObject* renderer = dragState().source->renderer()) {
// FIXME: This doesn't work correctly with transforms.
FloatPoint absPos = renderer->localToAbsolute();
IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint(delta));
dragState().clipboard->setDragImageElement(dragState().source.get(), IntPoint(delta));
} else {
// The renderer has disappeared, this can happen if the onStartDrag handler has hidden
// the element in some way. In this case we just kill the drag.
......@@ -3569,17 +3566,16 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
// Invalidate clipboard here against anymore pasteboard writing for security. The drag
// image can still be changed as we drag, but not the pasteboard data.
dragState().m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
dragState().clipboard->setAccessPolicy(ClipboardImageWritable);
if (m_mouseDownMayStartDrag) {
// gather values from DHTML element, if it set any
srcOp = dragState().m_dragClipboard->sourceOperation();
// Gather values from DHTML element, if it set any.
srcOp = dragState().clipboard->sourceOperation();
// Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the
// drag with dragImage! Because of that dumb reentrancy, we may think we've not
// started the drag when that happens. So we have to assume it's started before we
// kick it off.
dragState().m_dragClipboard->setDragHasStarted();
// drag with dragImage! Because of that dumb reentrancy, we may think we've not
// started the drag when that happens. So we have to assume it's started before we kick it off.
dragState().clipboard->setDragHasStarted();
}
}
......@@ -3587,15 +3583,14 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
Page* page = m_frame->page();
DragController* dragController = page ? page->dragController() : 0;
m_didStartDrag = dragController && dragController->startDrag(m_frame, dragState(), srcOp, event.event(), m_mouseDownPos);
// In WebKit2 we could reenter this code and start another drag.
// On OS X this causes problems with the ownership of the pasteboard
// and the promised types.
// In WebKit2 we could re-enter this code and start another drag.
// On OS X this causes problems with the ownership of the pasteboard and the promised types.
if (m_didStartDrag) {
m_mouseDownMayStartDrag = false;
return true;
}
if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
// Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
if (dragState().source && dragState().shouldDispatchEvents) {
// Drag was canned at the last minute. We owe dragSource a dragend event.
dispatchDragSrcEvent(eventNames().dragendEvent, event.event());
m_mouseDownMayStartDrag = false;
}
......@@ -3603,9 +3598,9 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
cleanupDrag:
if (!m_mouseDownMayStartDrag) {
// something failed to start the drag, cleanup
// Something failed to start the drag, clean up.
freeClipboard();
dragState().m_dragSrc = 0;
dragState().source = 0;
}
// No more default handling (like selection), whether we're past the hysteresis bounds or not
......@@ -3945,9 +3940,10 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
continue;
} else
continue;
// FIXME: Is the following code different from just calling innerElement?
Node* node = result.innerNode();
ASSERT(node);
// Touch events should not go to text nodes
if (node->isTextNode())
node = EventPathWalker::parent(node);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment