Bug 375681, use drag event names from what-wg spec, also implement new drag and dragend events, r=smaug,sr=roc

This commit is contained in:
enndeakin@sympatico.ca 2007-04-11 21:37:39 -07:00
parent 192c1af8d2
commit 8b6667e253
41 changed files with 363 additions and 157 deletions

View File

@ -395,6 +395,22 @@ nsContentAreaDragDrop::DragExit(nsIDOMEvent* aMouseEvent)
}
NS_IMETHODIMP
nsContentAreaDragDrop::Drag(nsIDOMEvent* aMouseEvent)
{
// nothing really to do here.
return NS_OK;
}
NS_IMETHODIMP
nsContentAreaDragDrop::DragEnd(nsIDOMEvent* aMouseEvent)
{
// nothing really to do here.
return NS_OK;
}
//
// ExtractURLFromData
//

View File

@ -93,6 +93,8 @@ public:
NS_IMETHOD DragExit(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragDrop(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragGesture(nsIDOMEvent* aMouseEvent);
NS_IMETHOD Drag(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragEnd(nsIDOMEvent* aMouseEvent);
NS_IMETHOD HandleEvent(nsIDOMEvent *event);
private:

View File

@ -278,14 +278,19 @@ GK_ATOM(DOMNodeInsertedIntoDocument, "DOMNodeInsertedInfoDocument")
GK_ATOM(DOMNodeRemoved, "DOMNodeRemoved")
GK_ATOM(DOMNodeRemovedFromDocument, "DOMNodeRemovedFromDocument")
GK_ATOM(DOMSubtreeModified, "DOMSubtreeModified")
GK_ATOM(drag, "drag")
GK_ATOM(dragdrop, "dragdrop")
GK_ATOM(dragend, "dragend")
GK_ATOM(dragenter, "dragenter")
GK_ATOM(dragevent, "dragevent")
GK_ATOM(dragexit, "dragexit")
GK_ATOM(draggesture, "draggesture")
GK_ATOM(dragging, "dragging")
GK_ATOM(dragleave, "dragleave")
GK_ATOM(dragover, "dragover")
GK_ATOM(dragSession, "dragSession")
GK_ATOM(dragstart, "dragstart")
GK_ATOM(drop, "drop")
GK_ATOM(dropAfter, "dropAfter")
GK_ATOM(dropBefore, "dropBefore")
GK_ATOM(dropOn, "dropOn")
@ -559,11 +564,16 @@ GK_ATOM(onDOMNodeInsertedIntoDocument, "onDOMNodeInsertedIntoDocument")
GK_ATOM(onDOMNodeRemoved, "onDOMNodeRemoved")
GK_ATOM(onDOMNodeRemovedFromDocument, "onDOMNodeRemovedFromDocument")
GK_ATOM(onDOMSubtreeModified, "onDOMSubtreeModified")
GK_ATOM(ondrag, "ondrag")
GK_ATOM(ondragdrop, "ondragdrop")
GK_ATOM(ondragend, "ondragend")
GK_ATOM(ondragenter, "ondragenter")
GK_ATOM(ondragexit, "ondragexit")
GK_ATOM(ondraggesture, "ondraggesture")
GK_ATOM(ondragleave, "ondragleave")
GK_ATOM(ondragover, "ondragover")
GK_ATOM(ondragstart, "ondragstart")
GK_ATOM(ondrop, "ondrop")
GK_ATOM(onerror, "onerror")
GK_ATOM(onfocus, "onfocus")
GK_ATOM(onget, "onget")

View File

@ -472,7 +472,10 @@ nsHTMLContentSerializer::IsJavaScript(nsIAtom* aAttrNameAtom, const nsAString& a
|| (aAttrNameAtom == nsGkAtoms::oncommand) || (aAttrNameAtom == nsGkAtoms::oncommandupdate)
|| (aAttrNameAtom == nsGkAtoms::ondragdrop) || (aAttrNameAtom == nsGkAtoms::ondragenter)
|| (aAttrNameAtom == nsGkAtoms::ondragexit) || (aAttrNameAtom == nsGkAtoms::ondraggesture)
|| (aAttrNameAtom == nsGkAtoms::ondragover) || (aAttrNameAtom == nsGkAtoms::oninput);
|| (aAttrNameAtom == nsGkAtoms::ondragover) || (aAttrNameAtom == nsGkAtoms::ondragstart)
|| (aAttrNameAtom == nsGkAtoms::ondragleave) || (aAttrNameAtom == nsGkAtoms::ondrop)
|| (aAttrNameAtom == nsGkAtoms::ondragend) || (aAttrNameAtom == nsGkAtoms::ondrag)
|| (aAttrNameAtom == nsGkAtoms::oninput);
return result;
}

View File

@ -63,8 +63,9 @@ static const char* const sEventNames[] = {
"submit", "reset", "change", "select", "input", "paint" ,"text",
"compositionstart", "compositionend", "popupshowing", "popupshown",
"popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
"scroll","overflow", "underflow", "overflowchanged",
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
"drag", "dragend", "dragstart", "dragleave", "drop", "resize",
"scroll", "overflow", "underflow", "overflowchanged",
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
"DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
"DOMAttrModified", "DOMCharacterDataModified",
@ -1177,10 +1178,20 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
return sEventNames[eDOMEvents_dragover];
case NS_DRAGDROP_EXIT_SYNTH:
return sEventNames[eDOMEvents_dragexit];
case NS_DRAGDROP_DROP:
case NS_DRAGDROP_DRAGDROP:
return sEventNames[eDOMEvents_dragdrop];
case NS_DRAGDROP_GESTURE:
return sEventNames[eDOMEvents_draggesture];
case NS_DRAGDROP_DRAG:
return sEventNames[eDOMEvents_drag];
case NS_DRAGDROP_END:
return sEventNames[eDOMEvents_dragend];
case NS_DRAGDROP_START:
return sEventNames[eDOMEvents_dragstart];
case NS_DRAGDROP_LEAVE_SYNTH:
return sEventNames[eDOMEvents_dragleave];
case NS_DRAGDROP_DROP:
return sEventNames[eDOMEvents_drop];
case NS_SCROLLPORT_OVERFLOW:
return sEventNames[eDOMEvents_overflow];
case NS_SCROLLPORT_UNDERFLOW:

View File

@ -107,6 +107,11 @@ public:
eDOMEvents_dragexit,
eDOMEvents_dragdrop,
eDOMEvents_draggesture,
eDOMEvents_drag,
eDOMEvents_dragend,
eDOMEvents_dragstart,
eDOMEvents_dragleave,
eDOMEvents_drop,
eDOMEvents_resize,
eDOMEvents_scroll,
eDOMEvents_overflow,

View File

@ -261,11 +261,16 @@ static const EventDispatchData sLoadEvents[] = {
};
static const EventDispatchData sDragEvents[] = {
{ NS_DRAGDROP_ENTER, HANDLER(&nsIDOMDragListener::DragEnter) },
{ NS_DRAGDROP_OVER_SYNTH, HANDLER(&nsIDOMDragListener::DragOver) },
{ NS_DRAGDROP_EXIT_SYNTH, HANDLER(&nsIDOMDragListener::DragExit) },
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::DragDrop) },
{ NS_DRAGDROP_GESTURE, HANDLER(&nsIDOMDragListener::DragGesture) }
{ NS_DRAGDROP_ENTER, HANDLER(&nsIDOMDragListener::DragEnter) },
{ NS_DRAGDROP_OVER_SYNTH, HANDLER(&nsIDOMDragListener::DragOver) },
{ NS_DRAGDROP_EXIT_SYNTH, HANDLER(&nsIDOMDragListener::DragExit) },
{ NS_DRAGDROP_DRAGDROP, HANDLER(&nsIDOMDragListener::DragDrop) },
{ NS_DRAGDROP_GESTURE, HANDLER(&nsIDOMDragListener::DragGesture) },
{ NS_DRAGDROP_DRAG, HANDLER(&nsIDOMDragListener::Drag) },
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) },
{ NS_DRAGDROP_START, HANDLER(&nsIDOMDragListener::DragStart) },
{ NS_DRAGDROP_LEAVE_SYNTH, HANDLER(&nsIDOMDragListener::DragLeave) },
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::Drop) },
};
static const EventDispatchData sXULEvents[] = {

View File

@ -1716,11 +1716,16 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
// reentering GenerateDragGesture inside DOM event processing.
StopTrackingDragGesture();
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
// get the widget from the target frame
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE,
mCurrentTarget->GetWindow(), nsMouseEvent::eReal);
FillInEventFromGestureDown(&event);
nsMouseEvent startEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_START,
widget, nsMouseEvent::eReal);
FillInEventFromGestureDown(&startEvent);
nsMouseEvent gestureEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE,
widget, nsMouseEvent::eReal);
FillInEventFromGestureDown(&gestureEvent);
// Dispatch to the DOM. By setting mCurrentTarget we are faking
// out the ESM and telling it that the current target frame is
@ -1737,10 +1742,17 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
// Set the current target to the content for the mouse down
mCurrentTargetContent = targetContent;
// Dispatch to DOM
nsEventDispatcher::Dispatch(targetContent, aPresContext, &event, nsnull,
// Dispatch both the dragstart and draggesture events to the DOM
nsEventStatus status = nsEventStatus_eIgnore;
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
&status);
if (status != nsEventStatus_eConsumeNoDefault) {
status = nsEventStatus_eIgnore;
nsEventDispatcher::Dispatch(targetContent, aPresContext, &gestureEvent, nsnull,
&status);
}
// Note that frame event handling doesn't care about NS_DRAGDROP_GESTURE,
// which is just as well since we don't really know which frame to
// send it to
@ -2223,6 +2235,34 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
break;
case NS_DRAGDROP_DROP:
{
// now fire the dragdrop event, for compatibility with XUL
if (mCurrentTarget) {
nsCOMPtr<nsIContent> targetContent;
mCurrentTarget->GetContentForEvent(presContext, aEvent,
getter_AddRefs(targetContent));
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_DRAGDROP,
widget, nsMouseEvent::eReal);
nsMouseEvent* mouseEvent = NS_STATIC_CAST(nsMouseEvent*, aEvent);
event.refPoint = mouseEvent->refPoint;
event.isShift = mouseEvent->isShift;
event.isControl = mouseEvent->isControl;
event.isAlt = mouseEvent->isAlt;
event.isMeta = mouseEvent->isMeta;
nsEventStatus status = nsEventStatus_eIgnore;
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
if (presShell) {
presShell->HandleEventWithTarget(&event, mCurrentTarget,
targetContent, &status);
}
}
// fall through and call GenerateDragDropEnterExit
}
case NS_DRAGDROP_EXIT:
// clean up after ourselves. make sure we do this _after_ the event, else we'll
// clean up too early!
@ -2844,71 +2884,17 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent));
if ( mLastDragOverFrame ) {
//fire drag exit
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent),
NS_DRAGDROP_EXIT_SYNTH, aEvent->widget,
nsMouseEvent::eReal);
event.refPoint = aEvent->refPoint;
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
event.relatedTarget = targetContent;
//The frame has change but the content may not have. Check before dispatching to content
//The frame has changed but the content may not have. Check before dispatching to content
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
if ( lastContent != targetContent ) {
//XXX This event should still go somewhere!!
if (lastContent)
nsEventDispatcher::Dispatch(lastContent, aPresContext, &event,
nsnull, &status);
// clear the drag hover
if (status != nsEventStatus_eConsumeNoDefault )
SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER);
}
// Finally dispatch exit to the frame
if ( mLastDragOverFrame ) {
mLastDragOverFrame->HandleEvent(aPresContext, &event, &status);
}
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
targetContent, lastContent, mLastDragOverFrame);
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
targetContent, lastContent, mLastDragOverFrame);
}
//fire drag enter
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_ENTER,
aEvent->widget, nsMouseEvent::eReal);
event.refPoint = aEvent->refPoint;
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
event.relatedTarget = lastContent;
mCurrentTargetContent = targetContent;
//The frame has change but the content may not have. Check before dispatching to content
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (targetContent)
nsEventDispatcher::Dispatch(targetContent, aPresContext, &event,
nsnull, &status);
// set drag hover on this frame
if (status != nsEventStatus_eConsumeNoDefault)
SetContentState(targetContent, NS_EVENT_STATE_DRAGOVER);
}
// Finally dispatch to the frame
if (mCurrentTarget) {
//XXX Get the new frame
mCurrentTarget->HandleEvent(aPresContext, &event, &status);
}
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_ENTER,
lastContent, targetContent, mCurrentTarget);
mLastDragOverFrame = mCurrentTarget;
}
@ -2920,37 +2906,16 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
{
//This is actually the window mouse exit event.
if ( mLastDragOverFrame ) {
// fire mouseout
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_EXIT_SYNTH,
aEvent->widget, nsMouseEvent::eReal);
event.refPoint = aEvent->refPoint;
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
// dispatch to content via DOM
nsCOMPtr<nsIContent> lastContent;
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
mCurrentTargetContent = lastContent;
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
nsnull, lastContent, mLastDragOverFrame);
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
nsnull, lastContent, mLastDragOverFrame);
if (lastContent) {
nsEventDispatcher::Dispatch(lastContent, aPresContext, &event, nsnull,
&status);
if (status != nsEventStatus_eConsumeNoDefault)
SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER);
}
// Finally dispatch to the frame
if ( mLastDragOverFrame ) {
//XXX Get the new frame
mLastDragOverFrame->HandleEvent(aPresContext, &event, &status);
mLastDragOverFrame = nsnull;
}
}
mLastDragOverFrame = nsnull;
}
}
break;
}
@ -2962,6 +2927,43 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
FlushPendingEvents(aPresContext);
}
void
nsEventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
nsGUIEvent* aEvent,
PRUint32 aMsg,
nsIContent* aRelatedTarget,
nsIContent* aTargetContent,
nsWeakFrame& aTargetFrame)
{
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMsg,
aEvent->widget, nsMouseEvent::eReal);
event.refPoint = aEvent->refPoint;
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
event.isAlt = ((nsMouseEvent*)aEvent)->isAlt;
event.isMeta = ((nsMouseEvent*)aEvent)->isMeta;
event.relatedTarget = aRelatedTarget;
mCurrentTargetContent = aTargetContent;
if (aTargetContent != aRelatedTarget) {
//XXX This event should still go somewhere!!
if (aTargetContent)
nsEventDispatcher::Dispatch(aTargetContent, aPresContext, &event,
nsnull, &status);
// adjust the drag hover
if (status != nsEventStatus_eConsumeNoDefault)
SetContentState((aMsg == NS_DRAGDROP_ENTER) ? aTargetContent : nsnull,
NS_EVENT_STATE_DRAGOVER);
}
// Finally dispatch the event to the frame
if (aTargetFrame)
aTargetFrame->HandleEvent(aPresContext, &event, &status);
}
nsresult
nsEventStateManager::SetClickCount(nsPresContext* aPresContext,
nsMouseEvent *aEvent,

View File

@ -194,6 +194,20 @@ protected:
*/
void NotifyMouseOut(nsGUIEvent* aEvent, nsIContent* aMovingInto);
void GenerateDragDropEnterExit(nsPresContext* aPresContext, nsGUIEvent* aEvent);
/**
* Fire the dragenter and dragexit/dragleave events when the mouse moves to a
* new target.
*
* @param aRelatedTarget relatedTarget to set for the event
* @param aTargetContent target to set for the event
* @param aTargetFrame target frame for the event
*/
void FireDragEnterOrExit(nsPresContext* aPresContext,
nsGUIEvent* aEvent,
PRUint32 aMsg,
nsIContent* aRelatedTarget,
nsIContent* aTargetContent,
nsWeakFrame& aTargetFrame);
nsresult SetClickCount(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
nsresult CheckForAndDispatchClick(nsPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
nsresult GetNextTabbableContent(nsIContent* aRootContent,

View File

@ -43,13 +43,17 @@
#include "nsIDOMEventListener.h"
/*
* Mouse up/down/move event listener
* The listener for drag events.
*
* The reason for two events for the same operation are for compatibility
* between the WHAT-WG drag and drop spec and existing XUL code.
*/
#define NS_IDOMDRAGLISTENER_IID \
{ /* 6b8b25d0-ded5-11d1-bd85-00805f8ae3f4 */ \
0x6b8b25d0, 0xded5, 0x11d1, \
{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
{ /* 1A107271-1E26-419A-BCF1-0A4CF7A66B45 */ \
0x1a107271, 0x1e26, 0x419a, \
{0xbc, 0xf1, 0x0a, 0x4c, 0xf7, 0xa6, 0x6b, 0x45} }
class nsIDOMDragListener : public nsIDOMEventListener {
@ -58,40 +62,81 @@ public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOMDRAGLISTENER_IID)
/**
* Processes a drag enter event
* The dragenter event is fired when the mouse is moved from one node onto
* another. The target is the node that the mouse is moved onto and the
* related target is the node that the mouse left.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragEnter(nsIDOMEvent* aMouseEvent) = 0;
/**
* Processes a drag over event
* The dragover event is fired at regular intervals (several times per second)
* while a drag is occuring. The target of this event is the node that the
* mouse is over.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragOver(nsIDOMEvent* aMouseEvent) = 0;
/**
* Processes a drag Exit event
* The dragleave event is fired when the mouse leaves a node for another
* node. The dragexit event is fired immediately afterwards which will
* call this method. The target is the node that the mouse left and the
* related target is the node that the mouse is entering. A dragenter
* event will be fired on the node that the mouse is entering after both
* the dragleave and dragexit event are fired.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragExit(nsIDOMEvent* aMouseEvent) = 0;
/**
* Processes a drag drop event
* The drop event will be fired on the node that the mouse is over once
* the drag is complete. The dragdrop event will be fired immediately
* afterwards which will call this method.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragDrop(nsIDOMEvent* aMouseEvent) = 0;
/**
* Processes a drag gesture event
* When the user begins a drag by pressing the mouse button and moving the
* mouse slightly, a dragstart event will be fired. Afterwards a draggesture
* event will be fired which will call this method.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragGesture(nsIDOMEvent* aMouseEvent) = 0;
/**
* The dragend event is fired when a drag is finished, whether the data was
* dropped successfully or whether the drag was cancelled. The target of
* this event is the source node of the drag.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD DragEnd(nsIDOMEvent* aMouseEvent) = 0;
/**
* The drag event is fired just before a dragover event is fired. The target
* of this event is the source node of the drag.
*
* @param aMouseEvent @see nsIDOMEvent.h
* @returns whether the event was consumed or ignored. @see nsresult
*/
NS_IMETHOD Drag(nsIDOMEvent* aMouseEvent) = 0;
// these methods are for compatibility
NS_IMETHOD DragStart(nsIDOMEvent* aMouseEvent) { return NS_OK; }
NS_IMETHOD DragLeave(nsIDOMEvent* aMouseEvent) { return NS_OK; }
NS_IMETHOD Drop(nsIDOMEvent* aMouseEvent) { return NS_OK; }
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMDragListener, NS_IDOMDRAGLISTENER_IID)

View File

@ -672,6 +672,18 @@ nsTextEditorDragListener::DragDrop(nsIDOMEvent* aMouseEvent)
return mEditor->InsertFromDrop(aMouseEvent);
}
nsresult
nsTextEditorDragListener::Drag(nsIDOMEvent* aDragEvent)
{
return NS_OK;
}
nsresult
nsTextEditorDragListener::DragEnd(nsIDOMEvent* aDragEvent)
{
return NS_OK;
}
PRBool
nsTextEditorDragListener::CanDrop(nsIDOMEvent* aEvent)
{

View File

@ -223,6 +223,8 @@ public:
NS_IMETHOD DragExit(nsIDOMEvent* aDragEvent);
NS_IMETHOD DragDrop(nsIDOMEvent* aDragEvent);
NS_IMETHOD DragGesture(nsIDOMEvent* aDragEvent);
NS_IMETHOD Drag(nsIDOMEvent* aDragEvent);
NS_IMETHOD DragEnd(nsIDOMEvent* aDragEvent);
/*END implementations of dragevent handler interface*/
protected:

View File

@ -326,6 +326,8 @@ public:
NS_IMETHOD DragExit(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragDrop(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragGesture(nsIDOMEvent* aMouseEvent);
NS_IMETHOD Drag(nsIDOMEvent* aMouseEvent);
NS_IMETHOD DragEnd(nsIDOMEvent* aMouseEvent);
nsresult Destroy();
@ -2766,6 +2768,28 @@ nsresult nsPluginInstanceOwner::DragGesture(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
nsresult nsPluginInstanceOwner::Drag(nsIDOMEvent* aMouseEvent)
{
if (mInstance) {
// Let the plugin handle drag events.
aMouseEvent->PreventDefault();
aMouseEvent->StopPropagation();
}
return NS_OK;
}
nsresult nsPluginInstanceOwner::DragEnd(nsIDOMEvent* aMouseEvent)
{
if (mInstance) {
// Let the plugin handle drag events.
aMouseEvent->PreventDefault();
aMouseEvent->StopPropagation();
}
return NS_OK;
}
/*=============== nsIKeyListener ======================*/

View File

@ -245,10 +245,15 @@ class nsHashKey;
#define NS_DRAGDROP_ENTER (NS_DRAGDROP_EVENT_START)
#define NS_DRAGDROP_OVER (NS_DRAGDROP_EVENT_START + 1)
#define NS_DRAGDROP_EXIT (NS_DRAGDROP_EVENT_START + 2)
#define NS_DRAGDROP_DROP (NS_DRAGDROP_EVENT_START + 3)
#define NS_DRAGDROP_DRAGDROP (NS_DRAGDROP_EVENT_START + 3)
#define NS_DRAGDROP_GESTURE (NS_DRAGDROP_EVENT_START + 4)
#define NS_DRAGDROP_DRAG (NS_DRAGDROP_EVENT_START + 5)
#define NS_DRAGDROP_END (NS_DRAGDROP_EVENT_START + 6)
#define NS_DRAGDROP_START (NS_DRAGDROP_EVENT_START + 7)
#define NS_DRAGDROP_DROP (NS_DRAGDROP_EVENT_START + 8)
#define NS_DRAGDROP_OVER_SYNTH (NS_DRAGDROP_EVENT_START + 1)
#define NS_DRAGDROP_EXIT_SYNTH (NS_DRAGDROP_EVENT_START + 2)
#define NS_DRAGDROP_LEAVE_SYNTH (NS_DRAGDROP_EVENT_START + 9)
// Events for popups
#define NS_XUL_EVENT_START 1500

View File

@ -47,7 +47,7 @@ interface nsIDOMNode;
interface nsIDOMMouseEvent;
interface nsISelection;
[scriptable, uuid(D2875740-95D3-4F12-8E97-9FAB76C87093)]
[scriptable, uuid(E8CD74A6-8BB6-4D27-9C65-4ED1B4398F8C)]
interface nsIDragService : nsISupports
{
const long DRAGDROP_ACTION_NONE = 0;
@ -124,9 +124,16 @@ interface nsIDragService : nsISupports
/**
* Tells the Drag Service to end a drag session. This is called when
* an external drag occurs
*
* If aDoneDrag is true, the drag has finished, otherwise the drag has
* just left the window.
*/
void endDragSession ( ) ;
void endDragSession ( in PRBool aDoneDrag ) ;
/**
* Fire a drag event at the source of the drag
*/
void fireDragEventAtSource ( in unsigned long aMsg );
};

View File

@ -338,7 +338,7 @@ nsDragService::StartDragSession()
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::EndDragSession()
nsDragService::EndDragSession(PRBool aDoneDrag)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::EndDragSession()"));
//Don't reset drag info, keep it until there is a new drag, in case a negotiated drag'n'drop wants the info.
@ -347,7 +347,7 @@ nsDragService::EndDragSession()
//That way the dragsession is always ended when we go outside mozilla windows, but we do throw away the
// mSourceDocument and mSourceNode. We do hold on to the nsTransferable if it was a internal drag.
//ResetDragInfo();
return nsBaseDragService::EndDragSession();
return nsBaseDragService::EndDragSession(aDoneDrag);
}
//-------------------------------------------------------------------------

View File

@ -64,7 +64,7 @@ public:
nsIScriptableRegion * aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDoneDrag);
// nsIDragSession
NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems);

View File

@ -2006,7 +2006,7 @@ bool nsWindow::CallMethod(MethodInfo *info)
NS_RELEASE(event.widget);
if (dragService)
dragService->EndDragSession();
dragService->EndDragSession(PR_TRUE);
}
break;
@ -3106,11 +3106,16 @@ void nsViewBeOS::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
if (msg == NULL)
break;
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
dragService->EndDragSession();
dragService->EndDragSession(PR_FALSE);
}
break;
default:
args[0]= msg == NULL ? NS_MOUSE_MOVE : NS_DRAGDROP_OVER;
// fire the drag event at the source
if (msg != NULL) {
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
dragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
}
}
MethodInfo *moveInfo = nsnull;

View File

@ -3689,8 +3689,12 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
nsCOMPtr<nsIDragSession> dragSession;
mDragService->GetCurrentSession(getter_AddRefs(dragSession));
if (dragSession) {
if (aMessage == NS_DRAGDROP_OVER)
if (aMessage == NS_DRAGDROP_OVER) {
// fire the drag event at the source. Just ignore whether it was
// cancelled or not as there isn't actually a means to stop the drag
mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
dragSession->SetCanDrop(PR_FALSE);
}
else if (aMessage == NS_DRAGDROP_DROP) {
// We make the assuption that the dragOver handlers have correctly set
// the |canDrop| property of the Drag Session.
@ -3728,7 +3732,7 @@ static PRBool IsSpecialGeckoKey(UInt32 macKeyCode)
// initiated in a different app. End the drag session,
// since we're done with it for now (until the user
// drags back into mozilla).
mDragService->EndDragSession();
mDragService->EndDragSession(PR_FALSE);
}
}

View File

@ -364,7 +364,7 @@ nsDragService::InvokeDragSession(nsIDOMNode* aDOMNode, nsISupportsArray* aTransf
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
source:globalDragView
slideBack:YES];
nsBaseDragService::EndDragSession();
nsBaseDragService::EndDragSession(PR_TRUE);
return NS_OK;
}

View File

@ -230,12 +230,12 @@ nsDragService::StartDragSession()
}
NS_IMETHODIMP
nsDragService::EndDragSession()
nsDragService::EndDragSession(PRBool aDoneDrag)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::EndDragSession"));
// unset our drag action
SetDragAction(DRAGDROP_ACTION_NONE);
return nsBaseDragService::EndDragSession();
return nsBaseDragService::EndDragSession(aDoneDrag);
}
// nsIDragSession
@ -974,7 +974,7 @@ nsDragService::SourceEndDrag(void)
mSourceDataItems = 0;
// Inform the drag session that we're ending the drag.
EndDragSession();
EndDragSession(PR_TRUE);
}
static void

View File

@ -69,7 +69,7 @@ public:
nsIScriptableRegion * aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDragDone);
// nsIDragSession
NS_IMETHOD SetCanDrop (PRBool aCanDrop);

View File

@ -3430,7 +3430,7 @@ nsWindow::OnDragDropSignal (GtkWidget *aWidget,
// Make sure to end the drag session. If this drag started in a
// different app, we won't get a drag_end signal to end it from.
dragService->EndDragSession();
dragService->EndDragSession(PR_TRUE);
return TRUE;
}
@ -3501,7 +3501,7 @@ nsWindow::OnDragLeave(void)
// initiated in a different app. End the drag session, since
// we're done with it for now (until the user drags back into
// mozilla).
dragService->EndDragSession();
dragService->EndDragSession(PR_FALSE);
}
}
}

View File

@ -240,12 +240,12 @@ nsDragService::StartDragSession()
}
NS_IMETHODIMP
nsDragService::EndDragSession()
nsDragService::EndDragSession(PRBool aDoneDrag)
{
PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::EndDragSession"));
// unset our drag action
SetDragAction(DRAGDROP_ACTION_NONE);
return nsBaseDragService::EndDragSession();
return nsBaseDragService::EndDragSession(aDoneDrag);
}
// nsIDragSession
@ -1038,7 +1038,7 @@ nsDragService::SourceEndDrag(void)
mSourceDataItems = 0;
// Inform the drag session that we're ending the drag.
EndDragSession();
EndDragSession(PR_TRUE);
}
static void

View File

@ -69,7 +69,7 @@ public:
nsIScriptableRegion * aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDoneDrag);
// nsIDragSession
NS_IMETHOD SetCanDrop (PRBool aCanDrop);

View File

@ -2474,6 +2474,8 @@ nsWindow::OnDragMotionEvent(GtkWidget *aWidget,
// notify the drag service that we are starting a drag motion.
dragSessionGTK->TargetStartDragMotion();
dragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
nsMouseEvent event(PR_TRUE, NS_DRAGDROP_OVER, innerMostWidget,
nsMouseEvent::eReal);
@ -2632,7 +2634,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
// Make sure to end the drag session. If this drag started in a
// different app, we won't get a drag_end signal to end it from.
dragService->EndDragSession();
dragService->EndDragSession(PR_TRUE);
return TRUE;
}
@ -2684,7 +2686,7 @@ nsWindow::OnDragLeave(void)
// initiated in a different app. End the drag session,
// since we're done with it for now (until the user
// drags back into mozilla).
dragService->EndDragSession();
dragService->EndDragSession(PR_FALSE);
}
}
}

View File

@ -190,7 +190,7 @@ nsDragHelperService::Leave(DragReference inDragRef, nsIEventSink *inSink)
// initiated in a differnt app. End the drag session,
// since we're done with it for now (until the user
// drags back into mozilla).
mDragService->EndDragSession();
mDragService->EndDragSession(PR_FALSE);
}
}

View File

@ -318,7 +318,7 @@ nsDragService::InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTran
// reset by the dragTrackingHandler).
StartDragSession();
::TrackDrag ( theDragRef, &theEvent, theDragRgn );
EndDragSession();
EndDragSession(PR_TRUE);
// clean up after ourselves
::DisposeRgn ( theDragRgn );

View File

@ -237,6 +237,7 @@ NS_IMETHODIMP nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
mDoingDrag = PR_TRUE;
HWND hwndDest = DrgDrag(mDragWnd, pDragInfo, &dragimage, 1, VK_BUTTON2,
(void*)0x80000000L); // Don't lock the desktop PS
FireDragEventAtSource(NS_DRAGDROP_END);
mDoingDrag = PR_FALSE;
// do clean up; if the drop completed,
@ -352,7 +353,7 @@ NS_IMETHODIMP nsDragService::StartDragSession()
return NS_OK;
}
NS_IMETHODIMP nsDragService::EndDragSession()
NS_IMETHODIMP nsDragService::EndDragSession(PRBool aDragDone)
{
NS_ASSERTION(0, "OS/2 version of EndDragSession() should never be called!");
return NS_OK;

View File

@ -63,7 +63,7 @@ public:
nsIScriptableRegion* aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDoneDrag);
// nsIDragSession
NS_IMETHOD GetNumDropItems(PRUint32* aNumDropItems);

View File

@ -3922,6 +3922,8 @@ PRBool nsWindow::OnDragDropMsg(ULONG msg, MPARAM mp1, MPARAM mp2, MRESULT &mr)
switch (msg) {
case DM_DRAGOVER:
dragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
rv = dragSession->DragOverMsg((PDRAGINFO)mp1, mr, &dragFlags);
eventType = NS_DRAGDROP_OVER;
break;

View File

@ -1313,6 +1313,7 @@ int nsWidget::DndCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbi
break;
case Ph_EV_DND_MOTION: {
sDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
pWidget->ProcessDrag( cbinfo->event, NS_DRAGDROP_OVER, &ptrev->pos );
}
break;
@ -1321,18 +1322,18 @@ int nsWidget::DndCallback( PtWidget_t *widget, void *data, PtCallbackInfo_t *cbi
d = ( nsDragService * )sDragService;
if( d->SetDropData( (char*)cbdnd->data ) != NS_OK ) break;
pWidget->ProcessDrag( cbinfo->event, NS_DRAGDROP_DROP, &ptrev->pos );
sDragService->EndDragSession();
sDragService->EndDragSession(PR_TRUE);
((nsDragService*) sDragService)->SourceEndDrag();
break;
case Ph_EV_DND_LEAVE:
pWidget->ProcessDrag( cbinfo->event, NS_DRAGDROP_EXIT, &ptrev->pos );
sDragService->EndDragSession();
sDragService->EndDragSession(PR_FALSE);
break;
case Ph_EV_DND_CANCEL:
pWidget->ProcessDrag( cbinfo->event, NS_DRAGDROP_EXIT, &ptrev->pos );
sDragService->EndDragSession();
sDragService->EndDragSession(PR_TRUE);
((nsDragService*) sDragService)->SourceEndDrag();
break;
}

View File

@ -190,13 +190,13 @@ NS_IMETHODIMP nsDragService::StartDragSession()
return nsBaseDragService::StartDragSession();
}
NS_IMETHODIMP nsDragService::EndDragSession()
NS_IMETHODIMP nsDragService::EndDragSession(PRBool aDragDone)
{
#ifdef NS_DEBUG
printf(" DnD: EndDragSession\n");
#endif
mDragObject = 0;
return nsBaseDragService::EndDragSession();
return nsBaseDragService::EndDragSession(aDragDone);
}
// nsIDragSession

View File

@ -62,7 +62,7 @@ public:
nsIScriptableRegion *aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDragDone);
// nsIDragSession
NS_IMETHOD SetCanDrop(PRBool aCanDrop);

View File

@ -226,7 +226,7 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
}
// We're done dragging
EndDragSession();
EndDragSession(PR_TRUE);
// For some drag/drop interactions, IDataObject::SetData doesn't get
// called with a CFSTR_PERFORMEDDROPEFFECT format and the
@ -482,9 +482,9 @@ nsDragService::IsCollectionObject(IDataObject* inDataObj)
// w/out crashing when we're still holding onto their data
//
NS_IMETHODIMP
nsDragService::EndDragSession()
nsDragService::EndDragSession(PRBool aDoneDrag)
{
nsBaseDragService::EndDragSession();
nsBaseDragService::EndDragSession(aDoneDrag);
NS_IF_RELEASE(mDataObject);
return NS_OK;

View File

@ -68,7 +68,7 @@ public:
NS_IMETHOD GetData(nsITransferable * aTransferable, PRUint32 anItem);
NS_IMETHOD GetNumDropItems(PRUint32 * aNumItems);
NS_IMETHOD IsDataFlavorSupported(const char *aDataFlavor, PRBool *_retval);
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDoneDrag);
// native impl.
NS_IMETHOD SetIDataObject(IDataObject * aDataObj);

View File

@ -294,6 +294,8 @@ nsNativeDragTarget::DragOver(DWORD grfKeyState,
return ResultFromScode(E_FAIL);
}
mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
// Now process the native drag state and then dispatch the event
ProcessDrag(nsnull, NS_DRAGDROP_OVER, grfKeyState, pt, pdwEffect);
return S_OK;
@ -325,7 +327,7 @@ nsNativeDragTarget::DragLeave()
// initiated in a different app. End the drag session, since
// we're done with it for now (until the user drags back into
// mozilla).
mDragService->EndDragSession();
mDragService->EndDragSession(PR_FALSE);
}
}
@ -360,6 +362,6 @@ nsNativeDragTarget::Drop(LPDATAOBJECT pData,
ProcessDrag(pData, NS_DRAGDROP_DROP, grfKeyState, aPT, pdwEffect);
// tell the drag service we're done with the session
serv->EndDragSession();
serv->EndDragSession(PR_TRUE);
return S_OK;
}

View File

@ -1148,6 +1148,8 @@ void nsAppShell::HandleDragMotionEvent(XEvent *event, nsWidget *aWidget) {
if (currentlyDragging) {
dragServiceXlib->UpdatePosition(event->xmotion.x, event->xmotion.y);
dragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
nsMouseEvent mevent(PR_TRUE, NS_DRAGDROP_OVER, aWidget,
nsMouseEvent::eReal);
mevent.refPoint.x = event->xmotion.x;

View File

@ -139,7 +139,7 @@ NS_IMETHODIMP nsDragService::StartDragSession()
return nsBaseDragService::StartDragSession();
}
NS_IMETHODIMP nsDragService::EndDragSession()
NS_IMETHODIMP nsDragService::EndDragSession(PRBool aDoneDrag)
{
if (sWindow) {
XDestroyWindow(sDisplay, sWindow);
@ -147,7 +147,7 @@ NS_IMETHODIMP nsDragService::EndDragSession()
}
mDragging = PR_FALSE;
return nsBaseDragService::EndDragSession();
return nsBaseDragService::EndDragSession(aDoneDrag);
}
// nsIDragSession
@ -231,7 +231,7 @@ NS_IMETHODIMP nsDragService::GetData(nsITransferable *aTransferable, PRUint32 an
}
}
EndDragSession();
EndDragSession(PR_TRUE);
return NS_OK;
}

View File

@ -68,7 +68,7 @@ public:
nsIScriptableRegion * aRegion,
PRUint32 aActionType);
NS_IMETHOD StartDragSession();
NS_IMETHOD EndDragSession();
NS_IMETHOD EndDragSession(PRBool aDoneDrag);
// nsIDragSession
NS_IMETHOD GetCurrentSession (nsIDragSession **aSession);

View File

@ -68,6 +68,7 @@
#include "imgIRequest.h"
#include "nsIViewObserver.h"
#include "nsRegion.h"
#include "nsGUIEvent.h"
#ifdef MOZ_CAIRO_GFX
#include "gfxContext.h"
@ -324,12 +325,15 @@ nsBaseDragService::StartDragSession()
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsBaseDragService::EndDragSession()
nsBaseDragService::EndDragSession(PRBool aDoneDrag)
{
if (!mDoingDrag) {
return NS_ERROR_FAILURE;
}
if (aDoneDrag)
FireDragEventAtSource(NS_DRAGDROP_END);
mDoingDrag = PR_FALSE;
// release the source we've been holding on to.
@ -346,6 +350,26 @@ nsBaseDragService::EndDragSession()
return NS_OK;
}
NS_IMETHODIMP
nsBaseDragService::FireDragEventAtSource(PRUint32 aMsg)
{
if (mSourceNode) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mSourceDocument);
if (doc) {
nsCOMPtr<nsIPresShell> presShell = doc->GetShellAt(0);
if (presShell) {
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event(PR_TRUE, aMsg, nsnull, nsMouseEvent::eReal);
nsCOMPtr<nsIContent> content = do_QueryInterface(mSourceNode);
return presShell->HandleDOMEventWithTarget(content, &event, &status);
}
}
}
return NS_OK;
}
#ifdef MOZ_CAIRO_GFX
static nsIPresShell*