Bug 508479 - HTML5 Drag and Drop: Drop event on elements that are not drop targets, r=enn, sr=sicking
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -323,17 +323,35 @@ nsContentAreaDragDrop::DragOver(nsIDOMDr
if (sourceRoot && sourceRoot == eventRoot) {
dropAllowed = PR_FALSE;
}
}
}
}
- session->SetCanDrop(dropAllowed);
+ nsCOMPtr<nsIDOMNSEvent> e = do_QueryInterface(inEvent);
+ NS_ENSURE_STATE(e);
+ nsCOMPtr<nsIDOMEventTarget> target;
+ e->GetOriginalTarget(getter_AddRefs(target));
+ nsCOMPtr<nsINode> node = do_QueryInterface(target);
+ if (!node) {
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(target);
+ if (win) {
+ node = do_QueryInterface(win->GetExtantDocument());
+ }
+ }
+ PRBool isChrome =
+ node ? nsContentUtils::IsChromeDoc(node->GetOwnerDoc()) : PR_FALSE;
+ if (isChrome) {
+ session->SetCanDrop(dropAllowed);
+ } else if (dropAllowed) {
+ inEvent->PreventDefault();
+ }
+
return NS_OK;
}
//
// ExtractURLFromData
//
// build up a url from whatever data we get from the OS. How we
--- a/content/events/src/nsDOMEvent.cpp
+++ b/content/events/src/nsDOMEvent.cpp
@@ -454,17 +454,33 @@ nsDOMEvent::GetIsTrusted(PRBool *aIsTrus
return NS_OK;
}
NS_IMETHODIMP
nsDOMEvent::PreventDefault()
{
if (!(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL)) {
mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
+
+ // Need to set an extra flag for drag events.
+ if (mEvent->eventStructType == NS_DRAG_EVENT &&
+ NS_IS_TRUSTED_EVENT(mEvent)) {
+ nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->currentTarget);
+ if (!node) {
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mEvent->currentTarget);
+ if (win) {
+ node = do_QueryInterface(win->GetExtantDocument());
+ }
+ }
+ if (node && !nsContentUtils::IsChromeDoc(node->GetOwnerDoc())) {
+ mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT_CALLED_IN_CONTENT;
+ }
+ }
}
+
return NS_OK;
}
nsresult
nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
{
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventTypeArg);
mEvent->message = NS_USER_DEFINED_EVENT;
--- a/content/events/src/nsEventDispatcher.cpp
+++ b/content/events/src/nsEventDispatcher.cpp
@@ -41,16 +41,18 @@
#include "nsPresContext.h"
#include "nsIPrivateDOMEvent.h"
#include "nsEventListenerManager.h"
#include "nsContentUtils.h"
#include "nsDOMError.h"
#include "nsMutationEvent.h"
#include NEW_H
#include "nsFixedSizeAllocator.h"
+#include "nsINode.h"
+#include "nsPIDOMWindow.h"
#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0)
#define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1)
// nsEventTargetChainItem represents a single item in the event target chain.
class nsEventTargetChainItem
{
private:
@@ -439,16 +441,38 @@ nsEventDispatcher::Dispatch(nsISupports*
nsDispatchingCallback* aCallback,
nsCOMArray<nsPIDOMEventTarget>* aTargets)
{
NS_ASSERTION(aEvent, "Trying to dispatch without nsEvent!");
NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(aEvent),
NS_ERROR_ILLEGAL_VALUE);
NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");
+ if (aEvent->flags & NS_EVENT_FLAG_ONLY_CHROME_DISPATCH) {
+ nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
+ if (!node) {
+ nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
+ if (win) {
+ node = do_QueryInterface(win->GetExtantDocument());
+ }
+ }
+
+ NS_ENSURE_STATE(node);
+ nsIDocument* doc = node->GetOwnerDoc();
+ if (!nsContentUtils::IsChromeDoc(doc)) {
+ nsPIDOMWindow* win = doc ? doc->GetInnerWindow() : nsnull;
+ // If we can't dispatch the event to chrome, do nothing.
+ NS_ENSURE_TRUE(win && win->GetChromeEventHandler(), NS_OK);
+ // Set the target to be the original dispatch target,
+ aEvent->target = aTarget;
+ // but use chrome event handler for event target chain.
+ aTarget = win->GetChromeEventHandler();
+ }
+ }
+
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aTarget);
#ifdef DEBUG
if (aDOMEvent) {
nsCOMPtr<nsIPrivateDOMEvent> privEvt(do_QueryInterface(aDOMEvent));
if (privEvt) {
nsEvent* innerEvent = privEvt->GetInternalNSEvent();
NS_ASSERTION(innerEvent == aEvent,
"The inner event of aDOMEvent is not the same as aEvent!");
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -3037,16 +3037,23 @@ nsEventStateManager::PostHandleEvent(nsP
case NS_DRAGDROP_OVER:
{
NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "Expected a drag event");
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
if (!dragSession)
break;
+ // Reset the flag.
+ dragSession->SetOnlyChromeDrop(PR_FALSE);
+ if (mPresContext) {
+ EnsureDocument(mPresContext);
+ }
+ PRBool isChromeDoc = nsContentUtils::IsChromeDoc(mDocument);
+
// the initial dataTransfer is the one from the dragstart event that
// was set on the dragSession when the drag began.
nsCOMPtr<nsIDOMNSDataTransfer> dataTransfer;
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
do_QueryInterface(initialDataTransfer);
@@ -3112,16 +3119,26 @@ nsEventStateManager::PostHandleEvent(nsP
action = dropEffect;
if (action == nsIDragService::DRAGDROP_ACTION_NONE)
dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
// inform the drag session that a drop is allowed on this node.
dragSession->SetDragAction(action);
dragSession->SetCanDrop(action != nsIDragService::DRAGDROP_ACTION_NONE);
+
+ // For now, do this only for dragover.
+ //XXXsmaug dragenter needs some more work.
+ if (aEvent->message == NS_DRAGDROP_OVER && !isChromeDoc) {
+ // Someone has called preventDefault(), check whether is was content.
+ dragSession->SetOnlyChromeDrop(
+ !(aEvent->flags & NS_EVENT_FLAG_NO_DEFAULT_CALLED_IN_CONTENT));
+ }
+ } else if (aEvent->message == NS_DRAGDROP_OVER && !isChromeDoc) {
+ dragSession->SetCanDrop(PR_FALSE);
}
// now set the drop effect in the initial dataTransfer. This ensures
// that we can get the desired drop effect in the drop event.
if (initialDataTransferNS)
initialDataTransferNS->SetDropEffectInt(dropEffect);
}
break;
--- a/content/events/test/Makefile.in
+++ b/content/events/test/Makefile.in
@@ -75,16 +75,17 @@ include $(topsrcdir)/config/rules.mk
test_bug457672.html \
test_bug428988.html \
bug457672.html \
test_draggableprop.html \
test_dragstart.html \
test_bug489671.html \
test_bug493251.html \
test_bug502818.html \
+ test_bug508479.html \
test_bug517851.html \
$(NULL)
_CHROME_FILES = \
test_bug415498.xul \
bug415498-doc1.html \
bug415498-doc2.html \
$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug508479.html
@@ -0,0 +1,81 @@
+<html>
+<head>
+ <title>Tests for the dragstart event</title>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+ <script type="application/javascript" src="/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<script>
+
+var gGotHandlingDrop = false;
+var gGotNotHandlingDrop = false;
+
+SimpleTest.waitForExplicitFinish();
+
+function fireEvent(target, event) {
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ var utils =
+ window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+ utils.dispatchDOMEventViaPresShell(target, event, true);
+}
+
+function fireDrop(element, dragData, effectAllowed) {
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ var ds = Components.classes["@mozilla.org/widget/dragservice;1"].
+ getService(Components.interfaces.nsIDragService);
+
+ ds.startDragSession();
+
+ var event = document.createEvent("DragEvents");
+ event.initDragEvent("dragover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
+ fireEvent(element, event);
+
+ event = document.createEvent("DragEvents");
+ event.initDragEvent("drop", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, null);
+ fireEvent(element, event);
+
+ ds.endDragSession(false);
+ ok(!ds.getCurrentSession(), "There shouldn't be a drag session anymore!");
+}
+
+function runTests()
+{
+ var targetHandling = document.getElementById("handling_target");
+ fireDrop(targetHandling, [{"test/plain": "Hello!"}]);
+
+ is(gGotHandlingDrop, true, "Got drop on accepting element (1)");
+ is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (1)");
+
+ // reset
+ gGotHandlingDrop = false;
+ gGotNotHandlingDrop = false;
+
+ var targetNotHandling = document.getElementById("nothandling_target");
+ fireDrop(targetNotHandling, [{"test/plain": "Hello!"}]);
+
+ is(gGotHandlingDrop, false, "Didn't get drop on accepting element (2)");
+ is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (2)");
+
+ SimpleTest.finish();
+}
+
+</script>
+
+<body onload="window.setTimeout(runTests, 0);">
+
+<img style="width: 100px; height: 100px;"
+ src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
+ id="handling_target"
+ ondragenter="event.preventDefault()"
+ ondragover="event.preventDefault()"
+ ondrop="gGotHandlingDrop = true;">
+
+<img style="width: 100px; height: 100px;"
+ src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
+ id="nothandling_target"
+ ondrop="gGotNotHandlingDrop = true;">
+
+</body>
+</html>
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -35,17 +35,17 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDocShell.h"
#include "nsPresContext.h"
#include "nsDOMClassInfo.h"
#include "nsDOMError.h"
#include "nsIDOMNSEvent.h"
-
+#include "nsIPrivateDOMEvent.h"
#include "nsDOMWindowUtils.h"
#include "nsGlobalWindow.h"
#include "nsIDocument.h"
#include "nsFocusManager.h"
#include "nsIEventStateManager.h"
#include "nsIScrollableView.h"
@@ -915,8 +915,37 @@ nsDOMWindowUtils::GetCOWForObject()
object, rval);
if (NS_FAILED(rv))
return rv;
cc->SetReturnValueWasSet(PR_TRUE);
return NS_OK;
}
+
+NS_IMETHODIMP
+nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
+ nsIDOMEvent* aEvent,
+ PRBool aTrusted,
+ PRBool* aRetVal)
+{
+ if (!nsContentUtils::IsCallerTrustedForRead()) {
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+
+ nsPresContext* presContext = GetPresContext();
+ NS_ENSURE_STATE(presContext);
+ nsCOMPtr<nsIPresShell> shell = presContext->GetPresShell();
+ NS_ENSURE_STATE(shell);
+ nsCOMPtr<nsIPrivateDOMEvent> event = do_QueryInterface(aEvent);
+ NS_ENSURE_STATE(event);
+ event->SetTrusted(aTrusted);
+ nsEvent* internalEvent = event->GetInternalNSEvent();
+ NS_ENSURE_STATE(internalEvent);
+ nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
+ NS_ENSURE_STATE(content);
+
+ nsEventStatus status = nsEventStatus_eIgnore;
+ shell->HandleEventWithTarget(internalEvent, nsnull, content,
+ &status);
+ *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
+ return NS_OK;
+}
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -40,20 +40,22 @@
/**
* nsIDOMWindowUtils is intended for infrequently-used methods related
* to the current nsIDOMWindow. Some of the methods may require
* elevated privileges; the method implementations should contain the
* necessary security checks. Access this interface by calling
* getInterface on a DOMWindow.
*/
+interface nsIDOMNode;
interface nsIDOMElement;
interface nsIDOMHTMLCanvasElement;
+interface nsIDOMEvent;
-[scriptable, uuid(4171ea1a-3752-4bc3-8c66-1b2936ecde7a)]
+[scriptable, uuid(4775e623-d596-4364-8637-0968a5ce5e3d)]
interface nsIDOMWindowUtils : nsISupports {
/**
* Image animation mode of the window. When this attribute's value
* is changed, the implementation should set all images in the window
* to the given value. That is, when set to kDontAnimMode, all images
* will stop animating. The attribute's value must be one of the
* animationMode values from imgIContainer.
@@ -398,9 +400,25 @@ interface nsIDOMWindowUtils : nsISupport
* Get IME status, see above IME_STATUS_* definitions.
*/
readonly attribute unsigned long IMEStatus;
/**
* Get the number of screen pixels per CSS pixel.
*/
readonly attribute float screenPixelsPerCSSPixel;
+
+ /**
+ * Dispatches aEvent via the nsIPresShell object of the window's document.
+ * The event is dispatched to aTarget, which should be an object
+ * which implements nsIContent interface (#element, #text, etc).
+ *
+ * Cannot be accessed from unprivileged context (not
+ * content-accessible) Will throw a DOM security error if called
+ * without UniversalXPConnect privileges.
+ *
+ * @note Event handlers won't get aEvent as parameter, but a similar event.
+ * Also, aEvent should not be reused.
+ */
+ boolean dispatchDOMEventViaPresShell(in nsIDOMNode aTarget,
+ in nsIDOMEvent aEvent,
+ in boolean aTrusted);
};
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6483,16 +6483,27 @@ PresShell::HandleEventInternal(nsEvent*
if (NS_IS_TRUSTED_EVENT(aEvent)) {
switch (aEvent->message) {
case NS_MOUSE_BUTTON_DOWN:
case NS_MOUSE_BUTTON_UP:
case NS_KEY_PRESS:
case NS_KEY_DOWN:
case NS_KEY_UP:
isHandlingUserInput = PR_TRUE;
+ break;
+ case NS_DRAGDROP_DROP:
+ nsCOMPtr<nsIDragSession> session = nsContentUtils::GetDragSession();
+ if (session) {
+ PRBool onlyChromeDrop = PR_FALSE;
+ session->GetOnlyChromeDrop(&onlyChromeDrop);
+ if (onlyChromeDrop) {
+ aEvent->flags |= NS_EVENT_FLAG_ONLY_CHROME_DISPATCH;
+ }
+ }
+ break;
}
}
if (aEvent->message == NS_CONTEXTMENU) {
nsMouseEvent* me = static_cast<nsMouseEvent*>(aEvent);
if (!CanHandleContextMenuEvent(me, GetCurrentEventFrame())) {
return NS_OK;
}
--- a/widget/public/nsGUIEvent.h
+++ b/widget/public/nsGUIEvent.h
@@ -127,16 +127,22 @@ class nsHashKey;
#define NS_EVENT_DISPATCHED 0x0400
#define NS_EVENT_FLAG_DISPATCHING 0x0800
// When an event is synthesized for testing, this flag will be set.
// Note that this is currently used only with mouse events, because this
// flag is not needed on other events now. It could be added to other
// events.
#define NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT 0x1000
+// Use this flag if the event should be dispatched only to chrome.
+#define NS_EVENT_FLAG_ONLY_CHROME_DISPATCH 0x2000
+
+// A flag for drag&drop handling.
+#define NS_EVENT_FLAG_NO_DEFAULT_CALLED_IN_CONTENT 0x4000
+
#define NS_PRIV_EVENT_UNTRUSTED_PERMITTED 0x8000
#define NS_EVENT_CAPTURE_MASK (~(NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))
#define NS_EVENT_BUBBLE_MASK (~(NS_EVENT_FLAG_CAPTURE | NS_EVENT_FLAG_NO_CONTENT_DISPATCH))
#define NS_EVENT_TYPE_NULL 0
/**
--- a/widget/public/nsIDragSession.idl
+++ b/widget/public/nsIDragSession.idl
@@ -48,24 +48,29 @@
native nsSize (nsSize);
interface nsIDOMDocument;
interface nsIDOMNode;
interface nsIDOMDataTransfer;
-[scriptable, uuid(15860D52-FE2C-4DDD-AC50-9C23E24916C4)]
+[scriptable, uuid(fde41f6a-c710-46f8-a0a8-1ff76ca4ff57)]
interface nsIDragSession : nsISupports
{
/**
* Set the current state of the drag, whether it can be dropped or not.
* usually the target "frame" sets this so the native system can render the correct feedback
*/
attribute boolean canDrop;
+
+ /**
+ * Indicates if the drop event should be dispatched only to chrome.
+ */
+ attribute boolean onlyChromeDrop;
/**
* Sets the action (copy, move, link, et.c) for the current drag
*/
attribute unsigned long dragAction;
/**
* Sets the current width and height of the drag target area.
--- a/widget/src/xpwidgets/nsBaseDragService.cpp
+++ b/widget/src/xpwidgets/nsBaseDragService.cpp
@@ -71,17 +71,18 @@
#include "nsIPrefService.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
#define DRAGIMAGES_PREF "nglayout.enable_drag_images"
nsBaseDragService::nsBaseDragService()
- : mCanDrop(PR_FALSE), mDoingDrag(PR_FALSE), mHasImage(PR_FALSE), mUserCancelled(PR_FALSE),
+ : mCanDrop(PR_FALSE), mOnlyChromeDrop(PR_FALSE), mDoingDrag(PR_FALSE),
+ mHasImage(PR_FALSE), mUserCancelled(PR_FALSE),
mDragAction(DRAGDROP_ACTION_NONE), mTargetSize(0,0),
mImageX(0), mImageY(0), mScreenX(-1), mScreenY(-1), mSuppressLevel(0)
{
}
nsBaseDragService::~nsBaseDragService()
{
}
@@ -98,16 +99,31 @@ nsBaseDragService::SetCanDrop(PRBool aCa
//---------------------------------------------------------
NS_IMETHODIMP
nsBaseDragService::GetCanDrop(PRBool * aCanDrop)
{
*aCanDrop = mCanDrop;
return NS_OK;
}
+//---------------------------------------------------------
+NS_IMETHODIMP
+nsBaseDragService::SetOnlyChromeDrop(PRBool aOnlyChrome)
+{
+ mOnlyChromeDrop = aOnlyChrome;
+ return NS_OK;
+}
+
+//---------------------------------------------------------
+NS_IMETHODIMP
+nsBaseDragService::GetOnlyChromeDrop(PRBool* aOnlyChrome)
+{
+ *aOnlyChrome = mOnlyChromeDrop;
+ return NS_OK;
+}
//---------------------------------------------------------
NS_IMETHODIMP
nsBaseDragService::SetDragAction(PRUint32 anAction)
{
mDragAction = anAction;
return NS_OK;
}
@@ -318,16 +334,18 @@ nsBaseDragService::GetCurrentSession(nsI
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsBaseDragService::StartDragSession()
{
if (mDoingDrag) {
return NS_ERROR_FAILURE;
}
mDoingDrag = PR_TRUE;
+ // By default dispatch drop also to content.
+ mOnlyChromeDrop = PR_FALSE;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsBaseDragService::EndDragSession(PRBool aDoneDrag)
{
if (!mDoingDrag) {
--- a/widget/src/xpwidgets/nsBaseDragService.h
+++ b/widget/src/xpwidgets/nsBaseDragService.h
@@ -123,16 +123,17 @@ protected:
/**
* Convert aScreenX and aScreenY from CSS pixels into unscaled device pixels.
*/
void
ConvertToUnscaledDevPixels(nsPresContext* aPresContext,
PRInt32* aScreenX, PRInt32* aScreenY);
PRPackedBool mCanDrop;
+ PRPackedBool mOnlyChromeDrop;
PRPackedBool mDoingDrag;
// true if mImage should be used to set a drag image
PRPackedBool mHasImage;
// true if the user cancelled the drag operation
PRPackedBool mUserCancelled;
PRUint32 mDragAction;
nsSize mTargetSize;