mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merged backout of bug 356295.
This commit is contained in:
commit
bda7a7aa7b
@ -188,6 +188,10 @@ var gImageHash = { };
|
||||
var gStrings = { };
|
||||
var gBundle;
|
||||
|
||||
const DRAGSERVICE_CONTRACTID = "@mozilla.org/widget/dragservice;1";
|
||||
const TRANSFERABLE_CONTRACTID = "@mozilla.org/widget/transferable;1";
|
||||
const ARRAY_CONTRACTID = "@mozilla.org/supports-array;1";
|
||||
const STRING_CONTRACTID = "@mozilla.org/supports-string;1";
|
||||
const PERMISSION_CONTRACTID = "@mozilla.org/permissionmanager;1";
|
||||
const PREFERENCES_CONTRACTID = "@mozilla.org/preferences-service;1";
|
||||
const ATOM_CONTRACTID = "@mozilla.org/atom-service;1";
|
||||
@ -659,16 +663,32 @@ function onBeginLinkDrag(event,urlField,descField)
|
||||
if (row == -1)
|
||||
return;
|
||||
|
||||
// Getting drag-system needed services
|
||||
var dragService = Components.classes[DRAGSERVICE_CONTRACTID].getService()
|
||||
.QueryInterface(Components.interfaces.nsIDragService);
|
||||
var transArray = Components.classes[ARRAY_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
var trans = Components.classes[TRANSFERABLE_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
if (!trans)
|
||||
return;
|
||||
|
||||
// Adding URL flavor
|
||||
trans.addDataFlavor("text/x-moz-url");
|
||||
var col = tree.columns[urlField];
|
||||
var url = tree.view.getCellText(row, col);
|
||||
col = tree.columns[descField];
|
||||
var desc = tree.view.getCellText(row, col);
|
||||
var stringURL = Components.classes[STRING_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
stringURL.data = url + "\n" + desc;
|
||||
trans.setTransferData("text/x-moz-url", stringURL, stringURL.data.length * 2 );
|
||||
transArray.AppendElement(trans.QueryInterface(Components.interfaces.nsISupports));
|
||||
|
||||
var dt = event.dataTransfer;
|
||||
dt.setData("text/x-moz-url", url + "\n" + desc);
|
||||
dt.setData("text/url-list", url);
|
||||
dt.setData("text/plain", url);
|
||||
dragService.invokeDragSession(event.target, transArray, null, dragService.DRAGDROP_ACTION_NONE);
|
||||
}
|
||||
|
||||
//******** Image Stuff
|
||||
|
@ -101,7 +101,6 @@ struct JSRuntime;
|
||||
class nsICaseConversion;
|
||||
class nsIUGenCategory;
|
||||
class nsIWidget;
|
||||
class nsIDragSession;
|
||||
class nsPIDOMWindow;
|
||||
#ifdef MOZ_XTF
|
||||
class nsIXTFService;
|
||||
@ -1219,11 +1218,6 @@ public:
|
||||
*/
|
||||
static void HidePopupsInDocument(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Retrieve the current drag session, or null if no drag is currently occuring
|
||||
*/
|
||||
static already_AddRefed<nsIDragSession> GetDragSession();
|
||||
|
||||
/**
|
||||
* Return true if aURI is a local file URI (i.e. file://).
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,6 @@ class nsIDocument;
|
||||
class nsIURI;
|
||||
class nsIFile;
|
||||
class nsISimpleEnumerator;
|
||||
class nsDOMDataTransfer;
|
||||
|
||||
// {1f34bc80-1bc7-11d6-a384-d705dd0746fc}
|
||||
#define NS_CONTENTAREADRAGDROP_CID \
|
||||
@ -77,11 +76,13 @@ class nsDOMDataTransfer;
|
||||
// RemoveChromeListeners().
|
||||
//
|
||||
class nsContentAreaDragDrop : public nsIDOMDragListener,
|
||||
public nsIDragDropHandler
|
||||
public nsIDragDropHandler,
|
||||
public nsIFlavorDataProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDRAGDROPHANDLER
|
||||
NS_DECL_NSIFLAVORDATAPROVIDER
|
||||
|
||||
nsContentAreaDragDrop();
|
||||
virtual ~nsContentAreaDragDrop();
|
||||
@ -96,33 +97,6 @@ public:
|
||||
NS_IMETHOD DragEnd(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *event);
|
||||
|
||||
/**
|
||||
* Determine what data in the content area, if any, is being dragged.
|
||||
*
|
||||
* aWindow - the window containing the target node
|
||||
* aTarget - the mousedown event target that started the drag
|
||||
* aSelectionTargetNode - the node where the drag event should be fired
|
||||
* aIsAltKeyPressed - true if the Alt key is pressed. In some cases, this
|
||||
* will prevent the drag from occuring. For example,
|
||||
* holding down Alt over a link should select the text,
|
||||
* not drag the link.
|
||||
* aDataTransfer - the dataTransfer for the drag event.
|
||||
* aCanDrag - [out] set to true if the drag may proceed, false to stop the
|
||||
* drag entirely
|
||||
* aDragSelection - [out] set to true to indicate that a selection is being
|
||||
* dragged, rather than a specific node
|
||||
* aDragNode - [out] the link, image or area being dragged, or null if the
|
||||
* drag occured on another element.
|
||||
*/
|
||||
static nsresult GetDragData(nsIDOMWindow* aWindow,
|
||||
nsIContent* aTarget,
|
||||
nsIContent* aSelectionTargetNode,
|
||||
PRBool aIsAltKeyPressed,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aCanDrag,
|
||||
PRBool* aDragSelection,
|
||||
nsIContent** aDragNode);
|
||||
|
||||
private:
|
||||
|
||||
// Add/remove the relevant listeners
|
||||
@ -135,9 +109,14 @@ private:
|
||||
static void GetEventDocument(nsIDOMEvent* inEvent,
|
||||
nsIDOMDocument** outDocument);
|
||||
|
||||
static void ExtractURLFromData(const nsACString & inFlavor,
|
||||
nsISupports* inDataWrapper, PRUint32 inDataLen,
|
||||
nsAString & outURL);
|
||||
static nsresult SaveURIToFile(nsAString& inSourceURIString,
|
||||
nsIFile* inDestFile);
|
||||
|
||||
void ExtractURLFromData(const nsACString & inFlavor,
|
||||
nsISupports* inDataWrapper, PRUint32 inDataLen,
|
||||
nsAString & outURL);
|
||||
nsresult GetHookEnumeratorFromEvent(nsIDOMEvent* inEvent,
|
||||
nsISimpleEnumerator** outEnumerator);
|
||||
|
||||
PRPackedBool mListenerInstalled;
|
||||
|
||||
@ -149,20 +128,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
// this is used to save images to disk lazily when the image data is asked for
|
||||
// during the drop instead of when it is added to the drag data transfer. This
|
||||
// ensures that the image data is only created when an image drop is allowed.
|
||||
class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFLAVORDATAPROVIDER
|
||||
|
||||
virtual ~nsContentAreaDragDropDataProvider() {}
|
||||
|
||||
nsresult SaveURIToFile(nsAString& inSourceURIString,
|
||||
nsIFile* inDestFile);
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsContentAreaDragDrop_h__ */
|
||||
|
@ -154,7 +154,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
||||
#include "nsAttrValue.h"
|
||||
#include "nsReferencedElement.h"
|
||||
#include "nsIUGenCategory.h"
|
||||
#include "nsIDragService.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsIBidiKeyboard.h"
|
||||
@ -418,16 +417,13 @@ nsContentUtils::InitializeEventTable() {
|
||||
{ &nsGkAtoms::oncommand, { NS_XUL_COMMAND, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onbroadcast, { NS_XUL_BROADCAST, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::oncommandupdate, { NS_XUL_COMMAND_UPDATE, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragenter, { NS_DRAGDROP_ENTER, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragover, { NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragenter, { NS_DRAGDROP_ENTER, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragover, { NS_DRAGDROP_OVER_SYNTH, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragexit, { NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragdrop, { NS_DRAGDROP_DRAGDROP, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragdrop, { NS_DRAGDROP_DROP, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondraggesture, { NS_DRAGDROP_GESTURE, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondrag, { NS_DRAGDROP_DRAG, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragend, { NS_DRAGDROP_END, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragstart, { NS_DRAGDROP_START, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragleave, { NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondrop, { NS_DRAGDROP_DROP, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondrag, { NS_DRAGDROP_DRAG, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragend, { NS_DRAGDROP_END, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onoverflow, { NS_SCROLLPORT_OVERFLOW, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onunderflow, { NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL }}
|
||||
#ifdef MOZ_SVG
|
||||
@ -4311,18 +4307,6 @@ nsContentUtils::HidePopupsInDocument(nsIDocument* aDocument)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsIDragSession>
|
||||
nsContentUtils::GetDragSession()
|
||||
{
|
||||
nsIDragSession* dragSession = nsnull;
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (dragService)
|
||||
dragService->GetCurrentSession(&dragSession);
|
||||
return dragSession;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
nsContentUtils::URIIsLocalFile(nsIURI *aURI)
|
||||
|
@ -310,14 +310,10 @@ GK_ATOM(dragend, "dragend")
|
||||
GK_ATOM(dragenter, "dragenter")
|
||||
GK_ATOM(dragevent, "dragevent")
|
||||
GK_ATOM(dragexit, "dragexit")
|
||||
GK_ATOM(draggable, "draggable")
|
||||
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")
|
||||
|
@ -83,8 +83,6 @@ NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContex
|
||||
nsresult
|
||||
NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsDragEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
|
||||
|
@ -76,7 +76,6 @@ CPPSRCS = \
|
||||
nsDOMTextEvent.cpp \
|
||||
nsDOMMouseEvent.cpp \
|
||||
nsDOMMouseScrollEvent.cpp \
|
||||
nsDOMDragEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMPopupBlockedEvent.cpp \
|
||||
nsDOMBeforeUnloadEvent.cpp \
|
||||
@ -93,7 +92,6 @@ CPPSRCS = \
|
||||
nsIMEStateManager.cpp \
|
||||
nsQueryContentEventHandler.cpp \
|
||||
nsDOMProgressEvent.cpp \
|
||||
nsDOMDataTransfer.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
@ -1,768 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMDataTransfer.h"
|
||||
|
||||
#include "prlog.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMLists.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIScriptableRegion.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_2(nsDOMDataTransfer, mDragTarget, mDragImage)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMDataTransfer)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMDataTransfer)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNSDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(DataTransfer)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
// the size of the array
|
||||
const char nsDOMDataTransfer::sEffects[8][9] = {
|
||||
"none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
|
||||
};
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer()
|
||||
: mEventType(NS_DRAGDROP_START),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED),
|
||||
mReadOnly(PR_FALSE),
|
||||
mIsExternal(PR_FALSE),
|
||||
mDragImageX(0),
|
||||
mDragImageY(0)
|
||||
{
|
||||
}
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction)
|
||||
: mEventType(aEventType),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mReadOnly(PR_TRUE),
|
||||
mIsExternal(PR_TRUE),
|
||||
mDragImageX(0),
|
||||
mDragImageY(0)
|
||||
{
|
||||
mEffectAllowed = aAction &
|
||||
(nsIDragService::DRAGDROP_ACTION_COPY |
|
||||
nsIDragService::DRAGDROP_ACTION_LINK |
|
||||
nsIDragService::DRAGDROP_ACTION_MOVE);
|
||||
|
||||
CacheExternalFormats();
|
||||
}
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType,
|
||||
const PRUint32 aEffectAllowed,
|
||||
PRBool aIsExternal,
|
||||
nsTArray<nsTArray<TransferItem> >& aItems,
|
||||
nsIDOMElement* aDragImage,
|
||||
PRUint32 aDragImageX,
|
||||
PRUint32 aDragImageY)
|
||||
: mEventType(aEventType),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mEffectAllowed(aEffectAllowed),
|
||||
mReadOnly(PR_TRUE),
|
||||
mIsExternal(aIsExternal),
|
||||
mItems(aItems),
|
||||
mDragImage(aDragImage),
|
||||
mDragImageX(aDragImageX),
|
||||
mDragImageY(aDragImageY)
|
||||
{
|
||||
// The items are copied from aItems into mItems. There is no need to copy
|
||||
// the actual data in the items as the data transfer will be read only. The
|
||||
// draggesture and dragstart events are the only times when items are
|
||||
// modifiable, but those events should have been using the first constructor
|
||||
// above.
|
||||
NS_ASSERTION(aEventType != NS_DRAGDROP_GESTURE &&
|
||||
aEventType != NS_DRAGDROP_START,
|
||||
"invalid event type for nsDOMDataTransfer constructor");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetDropEffect(nsAString& aDropEffect)
|
||||
{
|
||||
aDropEffect.AssignASCII(sEffects[mDropEffect]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDropEffect(const nsAString& aDropEffect)
|
||||
{
|
||||
// the drop effect can only be 'none', 'copy', 'move' or 'link'.
|
||||
for (PRUint32 e = 0; e <= nsIDragService::DRAGDROP_ACTION_LINK; e++) {
|
||||
if (aDropEffect.EqualsASCII(sEffects[e])) {
|
||||
// don't allow copyMove
|
||||
if (e != (nsIDragService::DRAGDROP_ACTION_COPY |
|
||||
nsIDragService::DRAGDROP_ACTION_MOVE))
|
||||
mDropEffect = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetEffectAllowed(nsAString& aEffectAllowed)
|
||||
{
|
||||
if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
aEffectAllowed.AssignLiteral("uninitialized");
|
||||
else
|
||||
aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetEffectAllowed(const nsAString& aEffectAllowed)
|
||||
{
|
||||
if (aEffectAllowed.EqualsLiteral("uninitialized")) {
|
||||
mEffectAllowed = nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_NONE == 0);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_COPY == 1);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_MOVE == 2);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_LINK == 4);
|
||||
|
||||
for (PRUint32 e = 0; e < NS_ARRAY_LENGTH(sEffects); e++) {
|
||||
if (aEffectAllowed.EqualsASCII(sEffects[e])) {
|
||||
mEffectAllowed = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetDropEffectInt(PRUint32* aDropEffect)
|
||||
{
|
||||
*aDropEffect = mDropEffect;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDropEffectInt(PRUint32 aDropEffect)
|
||||
{
|
||||
mDropEffect = aDropEffect;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetEffectAllowedInt(PRUint32* aEffectAllowed)
|
||||
{
|
||||
*aEffectAllowed = mEffectAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetEffectAllowedInt(PRUint32 aEffectAllowed)
|
||||
{
|
||||
mEffectAllowed = aEffectAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetTypes(nsIDOMDOMStringList** aTypes)
|
||||
{
|
||||
return MozTypesAt(0, aTypes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
|
||||
{
|
||||
// return an empty string if data for the format was not found
|
||||
aData.Truncate();
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
nsresult rv = MozGetDataAt(aFormat, 0, getter_AddRefs(data));
|
||||
if (rv == NS_ERROR_DOM_INDEX_SIZE_ERR)
|
||||
return NS_OK;
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (data) {
|
||||
nsAutoString stringdata;
|
||||
data->GetAsAString(stringdata);
|
||||
|
||||
// for the URL type, parse out the first URI from the list. The URIs are
|
||||
// separated by newlines
|
||||
if (aFormat.EqualsLiteral("URL")) {
|
||||
PRInt32 lastidx = 0, idx;
|
||||
PRInt32 length = stringdata.Length();
|
||||
while (lastidx < length) {
|
||||
idx = stringdata.FindChar('\n', lastidx);
|
||||
// lines beginning with # are comments
|
||||
if (stringdata[lastidx] == '#') {
|
||||
if (idx == -1)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (idx == -1)
|
||||
aData.Assign(Substring(stringdata, lastidx));
|
||||
else
|
||||
aData.Assign(Substring(stringdata, lastidx, idx - lastidx));
|
||||
aData = nsContentUtils::TrimWhitespace(aData, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
lastidx = idx + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aData = stringdata;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetData(const nsAString& aFormat, const nsAString& aData)
|
||||
{
|
||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
variant->SetAsAString(aData);
|
||||
|
||||
return MozSetDataAt(aFormat, variant, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::ClearData(const nsAString& aFormat)
|
||||
{
|
||||
nsresult rv = MozClearDataAt(aFormat, 0);
|
||||
return (rv == NS_ERROR_DOM_INDEX_SIZE_ERR) ? NS_OK : rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetMozItemCount(PRUint32* aCount)
|
||||
{
|
||||
*aCount = mItems.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozTypesAt(PRUint32 aIndex, nsIDOMDOMStringList** aTypes)
|
||||
{
|
||||
*aTypes = nsnull;
|
||||
|
||||
nsRefPtr<nsDOMStringList> types = new nsDOMStringList();
|
||||
NS_ENSURE_TRUE(types, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (aIndex < mItems.Length()) {
|
||||
// note that you can retrieve the types regardless of their principal
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
for (PRUint32 i = 0; i < item.Length(); i++)
|
||||
types->Add(item[i].mFormat);
|
||||
}
|
||||
|
||||
*aTypes = types;
|
||||
NS_ADDREF(*aTypes);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozGetDataAt(const nsAString& aFormat,
|
||||
PRUint32 aIndex,
|
||||
nsIVariant** aData)
|
||||
{
|
||||
*aData = nsnull;
|
||||
|
||||
if (aFormat.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (aIndex >= mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
|
||||
// allow access to any data in the drop and dragdrop events, or if the
|
||||
// UniversalBrowserRead privilege is set, otherwise only allow access to
|
||||
// data from the same principal.
|
||||
nsIPrincipal* principal = nsnull;
|
||||
if (mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
|
||||
!nsContentUtils::IsCallerTrustedForCapability("UniversalBrowserRead"))
|
||||
principal = GetCurrentPrincipal();
|
||||
|
||||
PRUint32 count = item.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
TransferItem& formatitem = item[i];
|
||||
if (formatitem.mFormat.Equals(format)) {
|
||||
PRBool subsumes;
|
||||
if (formatitem.mPrincipal && principal &&
|
||||
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
if (!formatitem.mData)
|
||||
FillInExternalDragData(formatitem, aIndex);
|
||||
*aData = formatitem.mData;
|
||||
NS_IF_ADDREF(*aData);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozSetDataAt(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex)
|
||||
{
|
||||
NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (aFormat.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
// Specifying an index less than the current length will replace an existing
|
||||
// item. Specifying an index equal to the current length will add a new item.
|
||||
if (aIndex > mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
// don't allow non-chrome to add file data
|
||||
// XXX perhaps this should also limit any non-string type as well
|
||||
if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
|
||||
aFormat.EqualsLiteral("application/x-moz-file")) &&
|
||||
!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
return SetDataWithPrincipal(aFormat, aData, aIndex, GetCurrentPrincipal());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozClearDataAt(const nsAString& aFormat, PRUint32 aIndex)
|
||||
{
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
if (aIndex >= mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
nsIPrincipal* principal = GetCurrentPrincipal();
|
||||
|
||||
// if the format is empty, clear all formats
|
||||
PRBool clearall = format.IsEmpty();
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
// count backwards so that the count and index don't have to be adjusted
|
||||
// after removing an element
|
||||
for (PRInt32 i = item.Length() - 1; i >= 0; i--) {
|
||||
TransferItem& formatitem = item[i];
|
||||
if (clearall || formatitem.mFormat.Equals(format)) {
|
||||
// don't allow removing data that has a stronger principal
|
||||
PRBool subsumes;
|
||||
if (formatitem.mPrincipal && principal &&
|
||||
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
item.RemoveElementAt(i);
|
||||
|
||||
// if a format was specified, break out. Otherwise, loop around until
|
||||
// all formats have been removed
|
||||
if (!clearall)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the last format for an item is removed, remove the entire item
|
||||
if (!item.Length())
|
||||
mItems.RemoveElementAt(aIndex);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDragImage(nsIDOMElement* aImage, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
mDragImage = aImage;
|
||||
mDragImageX = aX;
|
||||
mDragImageY = aY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::AddElement(nsIDOMElement* aElement)
|
||||
{
|
||||
NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
mDragTarget = do_QueryInterface(aElement);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataTransfer::Clone(PRUint32 aEventType,
|
||||
nsIDOMDataTransfer** aNewDataTransfer)
|
||||
{
|
||||
nsDOMDataTransfer* newDataTransfer =
|
||||
new nsDOMDataTransfer(aEventType, mEffectAllowed, mIsExternal,
|
||||
mItems, mDragImage, mDragImageX, mDragImageY);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aNewDataTransfer = newDataTransfer;
|
||||
NS_ADDREF(*aNewDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::GetTransferables(nsISupportsArray** aArray)
|
||||
{
|
||||
*aArray = nsnull;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> transArray =
|
||||
do_CreateInstance("@mozilla.org/supports-array;1");
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
PRBool added = PR_FALSE;
|
||||
PRUint32 count = mItems.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[i];
|
||||
PRUint32 count = item.Length();
|
||||
if (!count)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsITransferable> transferable =
|
||||
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
||||
if (!transferable)
|
||||
return;
|
||||
|
||||
for (PRUint32 f = 0; f < count; f++) {
|
||||
TransferItem& formatitem = item[f];
|
||||
if (!formatitem.mData) // skip empty items
|
||||
continue;
|
||||
|
||||
PRUint32 length;
|
||||
nsCOMPtr<nsISupports> convertedData;
|
||||
if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &length))
|
||||
continue;
|
||||
|
||||
// the underlying drag code uses text/unicode, so use that instead of text/plain
|
||||
const char* format;
|
||||
NS_ConvertUTF16toUTF8 utf8format(formatitem.mFormat);
|
||||
if (utf8format.EqualsLiteral("text/plain"))
|
||||
format = kUnicodeMime;
|
||||
else
|
||||
format = utf8format.get();
|
||||
|
||||
// if a converter is set for a format, set the converter for the
|
||||
// transferable and don't add the item
|
||||
nsCOMPtr<nsIFormatConverter> converter = do_QueryInterface(convertedData);
|
||||
if (converter) {
|
||||
transferable->AddDataFlavor(format);
|
||||
transferable->SetConverter(converter);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsresult rv = transferable->SetTransferData(format, convertedData, length);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
added = PR_TRUE;
|
||||
}
|
||||
|
||||
// only append the transferable if data was successfully added to it
|
||||
if (added)
|
||||
transArray->AppendElement(transferable);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aArray = transArray);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDOMDataTransfer::ConvertFromVariant(nsIVariant* aVariant,
|
||||
nsISupports** aSupports,
|
||||
PRUint32* aLength)
|
||||
{
|
||||
*aSupports = nsnull;
|
||||
*aLength = 0;
|
||||
|
||||
PRUint16 type;
|
||||
aVariant->GetDataType(&type);
|
||||
if (type == nsIDataType::VTYPE_INTERFACE ||
|
||||
type == nsIDataType::VTYPE_INTERFACE_IS) {
|
||||
if (NS_FAILED(aVariant->GetAsISupports(aSupports)))
|
||||
return PR_FALSE;
|
||||
|
||||
// for flavour data providers, use kFlavorHasDataProvider (which has the
|
||||
// value 0) as the length.
|
||||
nsCOMPtr<nsIFlavorDataProvider> fdp = do_QueryInterface(*aSupports);
|
||||
*aLength = fdp ? sizeof(nsISupports) : nsITransferable::kFlavorHasDataProvider;
|
||||
}
|
||||
|
||||
PRUnichar* chrs;
|
||||
nsresult rv = aVariant->GetAsWString(&chrs);
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsISupportsString>
|
||||
strSupports(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!strSupports)
|
||||
return PR_FALSE;
|
||||
|
||||
nsAutoString str(chrs);
|
||||
strSupports->SetData(str);
|
||||
|
||||
*aSupports = strSupports;
|
||||
NS_ADDREF(*aSupports);
|
||||
|
||||
// each character is two bytes
|
||||
*aLength = str.Length() << 1;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::ClearAll()
|
||||
{
|
||||
mItems.Clear();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataTransfer::SetDataWithPrincipal(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
// check if the item for the format already exists. In that case,
|
||||
// just replace it.
|
||||
TransferItem* formatitem;
|
||||
if (aIndex < mItems.Length()) {
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
PRUint32 count = item.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
TransferItem& itemformat = item[i];
|
||||
if (itemformat.mFormat.Equals(format)) {
|
||||
// don't allow replacing data that has a stronger principal
|
||||
PRBool subsumes;
|
||||
if (itemformat.mPrincipal && aPrincipal &&
|
||||
(NS_FAILED(aPrincipal->Subsumes(itemformat.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
itemformat.mPrincipal = aPrincipal;
|
||||
itemformat.mData = aData;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// add a new format
|
||||
formatitem = item.AppendElement();
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(aIndex == mItems.Length(), "Index out of range");
|
||||
|
||||
// add a new index
|
||||
nsTArray<TransferItem>* item = mItems.AppendElement();
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
formatitem = item->AppendElement();
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(formatitem, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
formatitem->mFormat = format;
|
||||
formatitem->mPrincipal = aPrincipal;
|
||||
formatitem->mData = aData;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsDOMDataTransfer::GetCurrentPrincipal()
|
||||
{
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> currentPrincipal;
|
||||
ssm->GetSubjectPrincipal(getter_AddRefs(currentPrincipal));
|
||||
if (!currentPrincipal)
|
||||
ssm->GetSystemPrincipal(getter_AddRefs(currentPrincipal));
|
||||
|
||||
return currentPrincipal.get();
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat)
|
||||
{
|
||||
// treat text/unicode as equivalent to text/plain
|
||||
if (aInFormat.EqualsLiteral("Text") || aInFormat.EqualsLiteral("text/unicode"))
|
||||
aOutFormat.AssignLiteral("text/plain");
|
||||
else if (aInFormat.EqualsLiteral("URL"))
|
||||
aOutFormat.AssignLiteral("text/uri-list");
|
||||
else
|
||||
aOutFormat.Assign(aInFormat);
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::CacheExternalFormats()
|
||||
{
|
||||
// Called during the constructor to cache the formats available from an
|
||||
// external drag. The data associated with each format will be set to null.
|
||||
// This data will instead only be retrieved in FillInExternalDragData when
|
||||
// asked for, as it may be time consuming for the source application to
|
||||
// generate it.
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (!dragSession)
|
||||
return;
|
||||
|
||||
// make sure that the system principal is used for external drags
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
nsCOMPtr<nsIPrincipal> sysPrincipal;
|
||||
ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
|
||||
|
||||
// there isn't a way to get a list of the formats that might be available on
|
||||
// all platforms, so just check for the types that can actually be imported
|
||||
// XXXndeakin there are some other formats but those are platform specific.
|
||||
const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime };
|
||||
|
||||
PRUint32 count;
|
||||
dragSession->GetNumDropItems(&count);
|
||||
for (PRUint32 c = 0; c < count; c++) {
|
||||
for (PRUint32 f = 0; f < NS_ARRAY_LENGTH(formats); f++) {
|
||||
// IsDataFlavorSupported doesn't take an index as an argument and just
|
||||
// checks if any of the items support a particular flavor, even though
|
||||
// the GetData method does take an index. Here, we just assume that
|
||||
// every item being dragged has the same set of flavors.
|
||||
PRBool supported;
|
||||
dragSession->IsDataFlavorSupported(formats[f], &supported);
|
||||
// if the format is supported, add an item to the array with null as
|
||||
// the data. When retrieved, GetRealData will read the data.
|
||||
if (supported) {
|
||||
if (formats[f] == kUnicodeMime) {
|
||||
SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nsnull, c, sysPrincipal);
|
||||
}
|
||||
else {
|
||||
if (formats[f] == kURLDataMime)
|
||||
SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nsnull, c, sysPrincipal);
|
||||
SetDataWithPrincipal(NS_ConvertUTF8toUTF16(formats[f]), nsnull, c, sysPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::FillInExternalDragData(TransferItem& aItem, PRUint32 aIndex)
|
||||
{
|
||||
NS_PRECONDITION(mIsExternal, "Not an external drag");
|
||||
|
||||
if (!aItem.mData) {
|
||||
nsCOMPtr<nsITransferable> trans =
|
||||
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
||||
if (!trans)
|
||||
return;
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
|
||||
const char* format = utf8format.get();
|
||||
if (strcmp(format, "text/plain") == 0)
|
||||
format = kUnicodeMime;
|
||||
else if (strcmp(format, "text/uri-list") == 0)
|
||||
format = kURLDataMime;
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (!dragSession)
|
||||
return;
|
||||
|
||||
trans->AddDataFlavor(format);
|
||||
dragSession->GetData(trans, aIndex);
|
||||
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsISupports> data;
|
||||
trans->GetTransferData(format, getter_AddRefs(data), &length);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
if (!variant)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISupportsString> supportsstr = do_QueryInterface(data);
|
||||
if (supportsstr) {
|
||||
nsAutoString str;
|
||||
supportsstr->GetData(str);
|
||||
variant->SetAsAString(str);
|
||||
}
|
||||
else {
|
||||
variant->SetAsISupports(data);
|
||||
}
|
||||
aItem.mData = variant;
|
||||
}
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMDataTransfer_h__
|
||||
#define nsDOMDataTransfer_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsITransferable;
|
||||
|
||||
/**
|
||||
* TransferItem is used to hold data for a particular format. Each piece of
|
||||
* data has a principal set from the caller which added it. This allows a
|
||||
* caller that wishes to retrieve the data to only be able to access the data
|
||||
* it is allowed to, yet still allow a chrome caller to retrieve any of the
|
||||
* data.
|
||||
*/
|
||||
struct TransferItem {
|
||||
nsString mFormat;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIVariant> mData;
|
||||
};
|
||||
|
||||
class nsDOMDataTransfer : public nsIDOMDataTransfer,
|
||||
public nsIDOMNSDataTransfer
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIDOMDATATRANSFER
|
||||
NS_DECL_NSIDOMNSDATATRANSFER
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMDataTransfer, nsIDOMDataTransfer)
|
||||
|
||||
friend class nsDOMDragEvent;
|
||||
friend class nsEventStateManager;
|
||||
|
||||
protected:
|
||||
|
||||
// the constructors are protected so only our friends can call them
|
||||
|
||||
// default constructor used for the dragstart/draggesture event and
|
||||
// synthetic events
|
||||
nsDOMDataTransfer();
|
||||
|
||||
// this constructor must only be used to create a dataTransfer for a drag
|
||||
// that was started without using a data transfer, either an external drag,
|
||||
// that is, a drag where the source is another application, or a drag
|
||||
// started by calling the drag service directly.
|
||||
nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction);
|
||||
|
||||
// this constructor is used only by the Clone method to copy the fields as
|
||||
// needed to a new data transfer.
|
||||
nsDOMDataTransfer(PRUint32 aEventType,
|
||||
const PRUint32 aEffectAllowed,
|
||||
PRBool aIsExternal,
|
||||
nsTArray<nsTArray<TransferItem> >& aItems,
|
||||
nsIDOMElement* aDragImage,
|
||||
PRUint32 aDragImageX,
|
||||
PRUint32 aDragImageY);
|
||||
|
||||
static const char sEffects[8][9];
|
||||
|
||||
public:
|
||||
|
||||
void GetDragTarget(nsIDOMElement** aDragTarget)
|
||||
{
|
||||
*aDragTarget = mDragTarget;
|
||||
NS_IF_ADDREF(*aDragTarget);
|
||||
}
|
||||
|
||||
// a readonly dataTransfer cannot have new data added or existing data removed.
|
||||
// Only the dropEffect and effectAllowed may be modified.
|
||||
void SetReadOnly() { mReadOnly = PR_TRUE; }
|
||||
|
||||
// converts the data into an array of nsITransferable objects to be used for
|
||||
// drag and drop or clipboard operations.
|
||||
void GetTransferables(nsISupportsArray** transferables);
|
||||
|
||||
// converts the data in the variant to an nsISupportString if possible or
|
||||
// an nsISupports or null otherwise.
|
||||
PRBool ConvertFromVariant(nsIVariant* aVariant,
|
||||
nsISupports** aSupports,
|
||||
PRUint32* aLength);
|
||||
|
||||
// clears all of the data
|
||||
void ClearAll();
|
||||
|
||||
// Similar to SetData except also specifies the principal to store.
|
||||
// aData may be null when called from CacheExternalFormats.
|
||||
nsresult SetDataWithPrincipal(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
protected:
|
||||
|
||||
// returns a weak reference to the drag image
|
||||
nsIDOMElement* GetDragImage(PRInt32* aX, PRInt32* aY)
|
||||
{
|
||||
*aX = mDragImageX;
|
||||
*aY = mDragImageY;
|
||||
return mDragImage;
|
||||
}
|
||||
|
||||
// returns a weak reference to the current principal
|
||||
nsIPrincipal* GetCurrentPrincipal();
|
||||
|
||||
// converts some formats used for compatibility in aInFormat into aOutFormat.
|
||||
// Text and text/unicode become text/plain, and URL becomes text/uri-list
|
||||
void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat);
|
||||
|
||||
// caches the formats that exist in the drag service that were added by an
|
||||
// external drag
|
||||
void CacheExternalFormats();
|
||||
|
||||
// fills in the data field of aItem with the data from the drag service for
|
||||
// a given index.
|
||||
void FillInExternalDragData(TransferItem& aItem, PRUint32 aIndex);
|
||||
|
||||
// the event type this data transfer is for. This will correspond to an
|
||||
// event->message value.
|
||||
PRUint32 mEventType;
|
||||
|
||||
// the drop effect and effect allowed
|
||||
PRUint32 mDropEffect;
|
||||
PRUint32 mEffectAllowed;
|
||||
|
||||
// readonly data transfers may not be modified except the drop effect and
|
||||
// effect allowed.
|
||||
PRPackedBool mReadOnly;
|
||||
|
||||
// true for drags started without a data transfer, for example, those from
|
||||
// another application.
|
||||
PRPackedBool mIsExternal;
|
||||
|
||||
// array of items, each containing an array of format->data pairs
|
||||
nsTArray<nsTArray<TransferItem> > mItems;
|
||||
|
||||
// the target of the drag. The drag and dragend events will fire at this.
|
||||
nsCOMPtr<nsIDOMElement> mDragTarget;
|
||||
|
||||
// the custom drag image and coordinates within the image. If mDragImage is
|
||||
// null, the default image is created from the drag target.
|
||||
nsCOMPtr<nsIDOMElement> mDragImage;
|
||||
PRUint32 mDragImageX;
|
||||
PRUint32 mDragImageY;
|
||||
};
|
||||
|
||||
#endif // nsDOMDataTransfer_h__
|
||||
|
@ -1,246 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMDragEvent.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "nsIDragService.h"
|
||||
|
||||
nsDOMDragEvent::nsDOMDragEvent(nsPresContext* aPresContext,
|
||||
nsInputEvent* aEvent)
|
||||
: nsDOMMouseEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsDragEvent(PR_FALSE, 0, nsnull))
|
||||
{
|
||||
if (aEvent) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMDragEvent::~nsDOMDragEvent()
|
||||
{
|
||||
if (mEventIsInternal) {
|
||||
if (mEvent->eventStructType == NS_DRAG_EVENT)
|
||||
delete static_cast<nsDragEvent*>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMDragEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DragEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMMouseEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::InitDragEvent(const nsAString & aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
nsIDOMAbstractView* aView,
|
||||
PRInt32 aDetail,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
{
|
||||
nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mEventIsInternal && mEvent) {
|
||||
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
dragEvent->dataTransfer = aDataTransfer;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::InitDragEventNS(const nsAString & aNamespaceURIArg,
|
||||
const nsAString & aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
nsIDOMAbstractView* aView,
|
||||
PRInt32 aDetail,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
|
||||
{
|
||||
*aDataTransfer = nsnull;
|
||||
|
||||
if (!mEvent || mEvent->eventStructType != NS_DRAG_EVENT) {
|
||||
NS_WARNING("Tried to get dataTransfer from non-drag event!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// the dataTransfer field of the event caches the DataTransfer associated
|
||||
// with the drag. It is initialized when an attempt is made to retrieve it
|
||||
// rather that when the event is created to avoid duplicating the data when
|
||||
// no listener ever uses it.
|
||||
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
if (dragEvent->dataTransfer) {
|
||||
CallQueryInterface(dragEvent->dataTransfer, aDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// for synthetic events, just use the supplied data transfer object
|
||||
if (mEventIsInternal) {
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For draggesture and dragstart events, the data transfer object is
|
||||
// created before the event fires, so it should already be set. For other
|
||||
// drag events, get the object from the drag session.
|
||||
NS_ASSERTION(mEvent->message != NS_DRAGDROP_GESTURE &&
|
||||
mEvent->message != NS_DRAGDROP_START,
|
||||
"draggesture event created without a dataTransfer");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
|
||||
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
|
||||
if (!initialDataTransfer) {
|
||||
// A dataTransfer won't exist when a drag was started by some other
|
||||
// means, for instance calling the drag service directly, or a drag
|
||||
// from another application. In either case, a new dataTransfer should
|
||||
// be created that reflects the data. Pass true to the constructor for
|
||||
// the aIsExternal argument, so that only system access is allowed.
|
||||
PRUint32 action = 0;
|
||||
dragSession->GetDragAction(&action);
|
||||
initialDataTransfer =
|
||||
new nsDOMDataTransfer(mEvent->message, action);
|
||||
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// now set it in the drag session so we don't need to create it again
|
||||
dragSession->SetDataTransfer(initialDataTransfer);
|
||||
}
|
||||
|
||||
// each event should use a clone of the original dataTransfer.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
|
||||
do_QueryInterface(initialDataTransfer);
|
||||
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
|
||||
initialDataTransferNS->Clone(mEvent->message,
|
||||
getter_AddRefs(dragEvent->dataTransfer));
|
||||
NS_ENSURE_TRUE(dragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// for the dragenter and dragover events, initialize the drop effect
|
||||
// from the drop action, which platform specific widget code sets before
|
||||
// the event is fired based on the keyboard state.
|
||||
if (mEvent->message == NS_DRAGDROP_ENTER ||
|
||||
mEvent->message == NS_DRAGDROP_OVER) {
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 action, effectAllowed;
|
||||
dragSession->GetDragAction(&action);
|
||||
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
|
||||
}
|
||||
else if (mEvent->message == NS_DRAGDROP_DROP ||
|
||||
mEvent->message == NS_DRAGDROP_DRAGDROP ||
|
||||
mEvent->message == NS_DRAGDROP_END) {
|
||||
// For the drop and dragend events, set the drop effect based on the
|
||||
// last value that the dropEffect had. This will have been set in
|
||||
// nsEventStateManager::PostHandleEvent for the last dragenter or
|
||||
// dragover event.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 dropEffect;
|
||||
initialDataTransferNS->GetDropEffectInt(&dropEffect);
|
||||
newDataTransfer->SetDropEffectInt(dropEffect);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsDOMDragEvent::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
|
||||
{
|
||||
// It is possible for the drag action to include more than one action, but
|
||||
// the widget code which sets the action from the keyboard state should only
|
||||
// be including one. If multiple actions were set, we just consider them in
|
||||
// the following order:
|
||||
// copy, link, move
|
||||
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
|
||||
// Filter the action based on the effectAllowed. If the effectAllowed
|
||||
// doesn't include the action, then that action cannot be done, so adjust
|
||||
// the action to something that is allowed. For a copy, adjust to move or
|
||||
// link. For a move, adjust to copy or link. For a link, adjust to move or
|
||||
// link. Otherwise, use none.
|
||||
if (aAction & aEffectAllowed ||
|
||||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
return aAction;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
return nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
return nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
return nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
return nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsDragEvent *aEvent)
|
||||
{
|
||||
nsDOMDragEvent* event = new nsDOMDragEvent(aPresContext, aEvent);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(event, aInstancePtrResult);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMDragEvent_h__
|
||||
#define nsDOMDragEvent_h__
|
||||
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsDOMMouseEvent.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsEvent;
|
||||
|
||||
class nsDOMDragEvent : public nsIDOMDragEvent,
|
||||
public nsDOMMouseEvent
|
||||
{
|
||||
public:
|
||||
nsDOMDragEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
|
||||
virtual ~nsDOMDragEvent();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMDRAGEVENT
|
||||
|
||||
NS_FORWARD_TO_NSDOMMOUSEEVENT
|
||||
|
||||
// filters the action to fit within the effects allowed and returns it.
|
||||
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
|
||||
};
|
||||
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsDragEvent* aEvent);
|
||||
|
||||
#endif // nsDOMDragEvent_h__
|
@ -64,7 +64,7 @@ static const char* const sEventNames[] = {
|
||||
"compositionstart", "compositionend", "popupshowing", "popupshown",
|
||||
"popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
|
||||
"drag", "dragend", "dragstart", "dragleave", "drop", "resize",
|
||||
"drag", "dragend", "resize",
|
||||
"scroll", "overflow", "underflow", "overflowchanged",
|
||||
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
|
||||
"DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
|
||||
@ -172,9 +172,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
|
||||
break;
|
||||
case NS_DRAG_EVENT:
|
||||
static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer = nsnull;
|
||||
break;
|
||||
case NS_XUL_COMMAND_EVENT:
|
||||
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent = nsnull;
|
||||
break;
|
||||
@ -201,10 +198,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
|
||||
cb.NoteXPCOMChild(
|
||||
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget);
|
||||
break;
|
||||
case NS_DRAG_EVENT:
|
||||
cb.NoteXPCOMChild(
|
||||
static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer);
|
||||
break;
|
||||
case NS_XUL_COMMAND_EVENT:
|
||||
cb.NoteXPCOMChild(
|
||||
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent);
|
||||
@ -475,27 +468,6 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
||||
} else if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
if (atom == nsGkAtoms::onDOMMouseScroll)
|
||||
mEvent->message = NS_MOUSE_SCROLL;
|
||||
} else if (mEvent->eventStructType == NS_DRAG_EVENT) {
|
||||
if (atom == nsGkAtoms::ondragstart)
|
||||
mEvent->message = NS_DRAGDROP_START;
|
||||
else if (atom == nsGkAtoms::ondraggesture)
|
||||
mEvent->message = NS_DRAGDROP_GESTURE;
|
||||
else if (atom == nsGkAtoms::ondragenter)
|
||||
mEvent->message = NS_DRAGDROP_ENTER;
|
||||
else if (atom == nsGkAtoms::ondragover)
|
||||
mEvent->message = NS_DRAGDROP_OVER_SYNTH;
|
||||
else if (atom == nsGkAtoms::ondragleave)
|
||||
mEvent->message = NS_DRAGDROP_LEAVE_SYNTH;
|
||||
else if (atom == nsGkAtoms::ondragexit)
|
||||
mEvent->message = NS_DRAGDROP_EXIT;
|
||||
else if (atom == nsGkAtoms::ondrag)
|
||||
mEvent->message = NS_DRAGDROP_DRAG;
|
||||
else if (atom == nsGkAtoms::ondrop)
|
||||
mEvent->message = NS_DRAGDROP_DROP;
|
||||
else if (atom == nsGkAtoms::ondragdrop)
|
||||
mEvent->message = NS_DRAGDROP_DRAGDROP;
|
||||
else if (atom == nsGkAtoms::ondragend)
|
||||
mEvent->message = NS_DRAGDROP_END;
|
||||
} else if (mEvent->eventStructType == NS_KEY_EVENT) {
|
||||
if (atom == nsGkAtoms::onkeydown)
|
||||
mEvent->message = NS_KEY_DOWN;
|
||||
@ -788,21 +760,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
newEvent = mouseEvent;
|
||||
break;
|
||||
}
|
||||
case NS_DRAG_EVENT:
|
||||
{
|
||||
nsDragEvent* oldDragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
nsDragEvent* dragEvent =
|
||||
new nsDragEvent(PR_FALSE, msg, nsnull);
|
||||
NS_ENSURE_TRUE(dragEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
isInputEvent = PR_TRUE;
|
||||
dragEvent->dataTransfer = oldDragEvent->dataTransfer;
|
||||
dragEvent->clickCount = oldDragEvent->clickCount;
|
||||
dragEvent->acceptActivation = oldDragEvent->acceptActivation;
|
||||
dragEvent->relatedTarget = oldDragEvent->relatedTarget;
|
||||
dragEvent->button = oldDragEvent->button;
|
||||
newEvent = dragEvent;
|
||||
break;
|
||||
}
|
||||
case NS_MENU_EVENT:
|
||||
{
|
||||
newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
|
||||
@ -1341,7 +1298,7 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
||||
return sEventNames[eDOMEvents_dragover];
|
||||
case NS_DRAGDROP_EXIT_SYNTH:
|
||||
return sEventNames[eDOMEvents_dragexit];
|
||||
case NS_DRAGDROP_DRAGDROP:
|
||||
case NS_DRAGDROP_DROP:
|
||||
return sEventNames[eDOMEvents_dragdrop];
|
||||
case NS_DRAGDROP_GESTURE:
|
||||
return sEventNames[eDOMEvents_draggesture];
|
||||
@ -1349,12 +1306,6 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
||||
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:
|
||||
|
@ -103,9 +103,6 @@ public:
|
||||
eDOMEvents_draggesture,
|
||||
eDOMEvents_drag,
|
||||
eDOMEvents_dragend,
|
||||
eDOMEvents_dragstart,
|
||||
eDOMEvents_dragleave,
|
||||
eDOMEvents_drop,
|
||||
eDOMEvents_resize,
|
||||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
NS_IMETHOD GetWhich(PRUint32 *aWhich);
|
||||
};
|
||||
|
||||
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \
|
||||
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \
|
||||
NS_FORWARD_NSIDOMMOUSEEVENT(nsDOMMouseEvent::) \
|
||||
NS_FORWARD_TO_NSDOMUIEVENT
|
||||
|
||||
|
@ -122,11 +122,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMUIEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
nsPoint nsDOMUIEvent::GetScreenPoint() {
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
mEvent->eventStructType != NS_DRAG_EVENT)) {
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
!NS_IS_DRAG_EVENT(mEvent))) {
|
||||
return nsPoint(0, 0);
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ nsPoint nsDOMUIEvent::GetClientPoint() {
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
mEvent->eventStructType != NS_DRAG_EVENT) ||
|
||||
!NS_IS_DRAG_EVENT(mEvent)) ||
|
||||
!mPresContext ||
|
||||
!((nsGUIEvent*)mEvent)->widget) {
|
||||
return mClientPoint;
|
||||
|
@ -576,9 +576,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsInputEvent*>(aEvent));
|
||||
case NS_DRAG_EVENT:
|
||||
return NS_NewDOMDragEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsDragEvent*>(aEvent));
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsPopupBlockedEvent*>
|
||||
@ -625,9 +622,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("mousescrollevents"))
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("dragevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("dragevents"))
|
||||
return NS_NewDOMDragEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("keyevents"))
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
@ -262,13 +262,10 @@ 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_DRAGDROP, HANDLER(&nsIDOMDragListener::DragDrop) },
|
||||
{ NS_DRAGDROP_DROP, 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) }
|
||||
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sXULEvents[] = {
|
||||
|
@ -60,7 +60,6 @@
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
@ -114,11 +113,10 @@
|
||||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMAbstractView.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsDOMDragEvent.h"
|
||||
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsCaret.h"
|
||||
@ -142,14 +140,6 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDragSession.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "nsContentAreaDragDrop.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsITreeBoxObject.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <Events.h>
|
||||
#endif
|
||||
@ -863,10 +853,7 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
KillClickHoldTimer();
|
||||
break;
|
||||
#endif
|
||||
case NS_DRAGDROP_DROP:
|
||||
case NS_DRAGDROP_OVER:
|
||||
// NS_DRAGDROP_DROP is fired before NS_DRAGDROP_DRAGDROP so send
|
||||
// the enter/exit events before NS_DRAGDROP_DROP.
|
||||
GenerateDragDropEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
||||
break;
|
||||
case NS_GOTFOCUS:
|
||||
@ -1984,36 +1971,18 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
KillClickHoldTimer();
|
||||
#endif
|
||||
|
||||
nsRefPtr<nsDOMDataTransfer> dataTransfer = new nsDOMDataTransfer();
|
||||
if (!dataTransfer)
|
||||
return;
|
||||
|
||||
PRBool isSelection = PR_FALSE;
|
||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||
mCurrentTarget->GetContentForEvent(aPresContext, aEvent,
|
||||
getter_AddRefs(eventContent));
|
||||
if (eventContent)
|
||||
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
|
||||
&isSelection, getter_AddRefs(targetContent));
|
||||
|
||||
nsCOMPtr<nsIContent> targetContent = mGestureDownContent;
|
||||
// Stop tracking the drag gesture now. This should stop us from
|
||||
// reentering GenerateDragGesture inside DOM event processing.
|
||||
StopTrackingDragGesture();
|
||||
|
||||
if (!targetContent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
|
||||
|
||||
// get the widget from the target frame
|
||||
nsDragEvent startEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_START, widget);
|
||||
FillInEventFromGestureDown(&startEvent);
|
||||
|
||||
nsDragEvent gestureEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE, widget);
|
||||
nsMouseEvent gestureEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE,
|
||||
widget, nsMouseEvent::eReal);
|
||||
FillInEventFromGestureDown(&gestureEvent);
|
||||
|
||||
startEvent.dataTransfer = gestureEvent.dataTransfer = dataTransfer;
|
||||
|
||||
// Dispatch to the DOM. By setting mCurrentTarget we are faking
|
||||
// out the ESM and telling it that the current target frame is
|
||||
// actually where the mouseDown occurred, otherwise it will use
|
||||
@ -2029,28 +1998,11 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
// Set the current target to the content for the mouse down
|
||||
mCurrentTargetContent = targetContent;
|
||||
|
||||
// Dispatch both the dragstart and draggesture events to the DOM
|
||||
// Dispatch the draggesture event to the DOM
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &gestureEvent, nsnull,
|
||||
&status);
|
||||
|
||||
nsDragEvent* event = &startEvent;
|
||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
status = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &gestureEvent, nsnull,
|
||||
&status);
|
||||
event = &gestureEvent;
|
||||
}
|
||||
|
||||
// now that the dataTransfer has been updated in the dragstart and
|
||||
// draggesture events, make it read only so that the data doesn't
|
||||
// change during the drag.
|
||||
dataTransfer->SetReadOnly();
|
||||
|
||||
if (status != nsEventStatus_eConsumeNoDefault)
|
||||
DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, isSelection);
|
||||
|
||||
// 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
|
||||
@ -2065,230 +2017,6 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
}
|
||||
} // GenerateDragGesture
|
||||
|
||||
void
|
||||
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||
nsIContent* aSelectionTarget,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aIsSelection,
|
||||
nsIContent** aTargetNode)
|
||||
{
|
||||
*aTargetNode = nsnull;
|
||||
|
||||
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
|
||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
|
||||
|
||||
// GetDragData determines if a selection, link or image in the content
|
||||
// should be dragged, and places the data associated with the drag in the
|
||||
// data transfer. Skip this check for chrome shells.
|
||||
PRBool canDrag;
|
||||
nsCOMPtr<nsIContent> dragDataNode;
|
||||
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
|
||||
if (dsti) {
|
||||
PRInt32 type = -1;
|
||||
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
|
||||
type != nsIDocShellTreeItem::typeChrome) {
|
||||
// mGestureDownContent is the node where the mousedown event for the drag
|
||||
// occured, and aSelectionTarget is the node to use when a selection is used
|
||||
nsresult rv =
|
||||
nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
|
||||
aSelectionTarget, mGestureDownAlt,
|
||||
aDataTransfer, &canDrag, aIsSelection,
|
||||
getter_AddRefs(dragDataNode));
|
||||
if (NS_FAILED(rv) || !canDrag)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if GetDragData returned a node, use that as the node being dragged.
|
||||
// Otherwise, if a selection is being dragged, use the node within the
|
||||
// selection that was dragged. Otherwise, just use the mousedown target.
|
||||
nsIContent* dragContent = mGestureDownContent;
|
||||
if (dragDataNode)
|
||||
dragContent = dragDataNode;
|
||||
else if (*aIsSelection)
|
||||
dragContent = aSelectionTarget;
|
||||
|
||||
nsIContent* originalDragContent = dragContent;
|
||||
|
||||
// If a selection isn't being dragged, look for an ancestor with the
|
||||
// draggable property set. If one is found, use that as the target of the
|
||||
// drag instead of the node that was clicked on. If a draggable node wasn't
|
||||
// found, just use the clicked node.
|
||||
if (!*aIsSelection) {
|
||||
while (dragContent) {
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(dragContent);
|
||||
if (htmlElement) {
|
||||
PRBool draggable = PR_FALSE;
|
||||
htmlElement->GetDraggable(&draggable);
|
||||
if (draggable)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(dragContent);
|
||||
if (xulElement) {
|
||||
// All XUL elements are draggable, so if a XUL element is
|
||||
// encountered, stop looking for draggable nodes and just use the
|
||||
// original clicked node instead.
|
||||
// XXXndeakin
|
||||
// In the future, we will want to improve this so that XUL has a
|
||||
// better way to specify whether something is draggable than just
|
||||
// on/off.
|
||||
dragContent = mGestureDownContent;
|
||||
break;
|
||||
}
|
||||
// otherwise, it's not an HTML or XUL element, so just keep looking
|
||||
}
|
||||
dragContent = dragContent->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
// if no node in the hierarchy was found to drag, but the GetDragData method
|
||||
// returned a node, use that returned node. Otherwise, just use the original
|
||||
// node that was clicked.
|
||||
if (!dragContent) {
|
||||
if (dragDataNode)
|
||||
dragContent = originalDragContent;
|
||||
else
|
||||
dragContent = mGestureDownContent;
|
||||
}
|
||||
|
||||
if (dragContent) {
|
||||
// if an ancestor node was used instead, clear the drag data
|
||||
// XXXndeakin rework this a bit. Find a way to just not call GetDragData if we don't need to.
|
||||
if (dragContent != originalDragContent)
|
||||
aDataTransfer->ClearAll();
|
||||
*aTargetNode = dragContent;
|
||||
NS_ADDREF(*aTargetNode);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection)
|
||||
{
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
// Default handling for the draggesture/dragstart event.
|
||||
//
|
||||
// First, check if a drag session already exists. This means that the drag
|
||||
// service was called directly within a draggesture handler. In this case,
|
||||
// don't do anything more, as it is assumed that the handler is managing
|
||||
// drag and drop manually.
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (dragSession)
|
||||
return; // already a drag in progress
|
||||
|
||||
// No drag session is currently active, so check if a handler added
|
||||
// any items to be dragged. If not, there isn't anything to drag.
|
||||
PRUint32 count = 0;
|
||||
if (aDataTransfer)
|
||||
aDataTransfer->GetMozItemCount(&count);
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
// Get the target being dragged, which may not be the same as the
|
||||
// target of the mouse event. If one wasn't set in the
|
||||
// aDataTransfer during the event handler, just use the original
|
||||
// target instead.
|
||||
nsCOMPtr<nsIDOMNode> dragTarget;
|
||||
nsCOMPtr<nsIDOMElement> dragTargetElement;
|
||||
aDataTransfer->GetDragTarget(getter_AddRefs(dragTargetElement));
|
||||
dragTarget = do_QueryInterface(dragTargetElement);
|
||||
if (!dragTarget) {
|
||||
dragTarget = do_QueryInterface(aDragTarget);
|
||||
if (!dragTarget)
|
||||
return;
|
||||
}
|
||||
|
||||
// check which drag effect should initially be used
|
||||
PRUint32 effectAllowed;
|
||||
aDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
|
||||
PRInt32 action = 0;
|
||||
if (effectAllowed != nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
action = effectAllowed;
|
||||
|
||||
// get any custom drag image that was set
|
||||
PRInt32 imageX, imageY;
|
||||
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
|
||||
|
||||
// If a selection is being dragged, and no custom drag image was
|
||||
// set, get the selection so that the drag region can be created
|
||||
// from the selection area. If a custom image was set, it doesn't
|
||||
// matter what the selection is since the image will be used instead.
|
||||
nsISelection* selection = nsnull;
|
||||
if (aIsSelection && !dragImage) {
|
||||
nsIDocument* doc = aDragTarget->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetPrimaryShell();
|
||||
if (presShell) {
|
||||
selection = presShell->GetCurrentSelection(
|
||||
nsISelectionController::SELECTION_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsArray> transArray;
|
||||
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
// XXXndeakin don't really want to create a new drag DOM event
|
||||
// here, but we need something to pass to the InvokeDragSession
|
||||
// methods.
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
NS_NewDOMDragEvent(getter_AddRefs(domEvent), aPresContext, aDragEvent);
|
||||
|
||||
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
|
||||
// if creating a drag event failed, starting a drag session will
|
||||
// just fail.
|
||||
if (selection) {
|
||||
dragService->InvokeDragSessionWithSelection(selection, transArray,
|
||||
action, domDragEvent,
|
||||
aDataTransfer);
|
||||
}
|
||||
else {
|
||||
// if dragging within a XUL tree and no custom drag image was
|
||||
// set, the region argument to InvokeDragSessionWithImage needs
|
||||
// to be set to the area encompassing the selected rows of the
|
||||
// tree to ensure that the drag feedback gets clipped to those
|
||||
// rows. For other content, region should be null.
|
||||
nsCOMPtr<nsIScriptableRegion> region;
|
||||
#ifdef MOZ_XUL
|
||||
if (dragTarget && !dragImage) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(dragTarget);
|
||||
if (content->NodeInfo()->Equals(nsGkAtoms::treechildren,
|
||||
kNameSpaceID_XUL)) {
|
||||
nsIDocument* doc = content->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetPrimaryShell();
|
||||
if (presShell) {
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(content);
|
||||
if (frame) {
|
||||
nsITreeBoxObject* treeBoxObject;
|
||||
CallQueryInterface(frame, &treeBoxObject);
|
||||
treeBoxObject->GetSelectionRegion(getter_AddRefs(region));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dragService->InvokeDragSessionWithImage(dragTarget, transArray,
|
||||
region, action, dragImage,
|
||||
imageX, imageY, domDragEvent,
|
||||
aDataTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv)
|
||||
{
|
||||
@ -2811,124 +2539,10 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
|
||||
break;
|
||||
|
||||
case NS_DRAGDROP_ENTER:
|
||||
case NS_DRAGDROP_OVER:
|
||||
{
|
||||
NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "Expected a drag event");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
if (!dragSession)
|
||||
break;
|
||||
|
||||
// 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);
|
||||
|
||||
// cancelling a dragenter or dragover event means that a drop should be
|
||||
// allowed, so update the dropEffect and the canDrop state to indicate
|
||||
// that a drag is allowed. If the event isn't cancelled, a drop won't be
|
||||
// allowed. Essentially, to allow a drop somewhere, specify the effects
|
||||
// using the effectAllowed and dropEffect properties in a dragenter or
|
||||
// dragover event and cancel the event. To not allow a drop somewhere,
|
||||
// don't cancel the event or set the effectAllowed or dropEffect to
|
||||
// "none". This way, if the event is just ignored, no drop will be
|
||||
// allowed.
|
||||
PRUint32 dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
if (nsEventStatus_eConsumeNoDefault == *aStatus) {
|
||||
// if the event has a dataTransfer set, use it.
|
||||
nsDragEvent *dragEvent = (nsDragEvent*)aEvent;
|
||||
if (dragEvent->dataTransfer) {
|
||||
// get the dataTransfer and the dropEffect that was set on it
|
||||
dataTransfer = do_QueryInterface(dragEvent->dataTransfer);
|
||||
dataTransfer->GetDropEffectInt(&dropEffect);
|
||||
}
|
||||
else {
|
||||
// if dragEvent->dataTransfer is null, it means that no attempt was
|
||||
// made to access the dataTransfer during the event, yet the event
|
||||
// was cancelled. Instead, use the initial data transfer available
|
||||
// from the drag session. The drop effect would not have been
|
||||
// initialized (which is done in nsDOMDragEvent::GetDataTransfer),
|
||||
// so set it from the drag action. We'll still want to filter it
|
||||
// based on the effectAllowed below.
|
||||
dataTransfer = initialDataTransferNS;
|
||||
|
||||
PRUint32 action;
|
||||
dragSession->GetDragAction(&action);
|
||||
|
||||
// filter the drop effect based on the action. Use UNINITIALIZED as
|
||||
// any effect is allowed.
|
||||
dropEffect = nsDOMDragEvent::FilterDropEffect(action,
|
||||
nsIDragService::DRAGDROP_ACTION_UNINITIALIZED);
|
||||
}
|
||||
|
||||
// At this point, if the dataTransfer is null, it means that the
|
||||
// drag was originally started by directly calling the drag service.
|
||||
// Just assume that all effects are allowed.
|
||||
PRUint32 effectAllowed = nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
||||
if (dataTransfer)
|
||||
dataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
|
||||
// set the drag action based on the drop effect and effect allowed.
|
||||
// The drop effect field on the drag transfer object specifies the
|
||||
// desired current drop effect. However, it cannot be used if the
|
||||
// effectAllowed state doesn't include that type of action. If the
|
||||
// dropEffect is "none", then the action will be 'none' so a drop will
|
||||
// not be allowed.
|
||||
PRUint32 action = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
if (effectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED ||
|
||||
dropEffect & effectAllowed)
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
case NS_DRAGDROP_DROP:
|
||||
{
|
||||
// now fire the dragdrop event, for compatibility with XUL
|
||||
if (mCurrentTarget && nsEventStatus_eConsumeNoDefault != *aStatus) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
mCurrentTarget->GetContentForEvent(presContext, aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
|
||||
nsDragEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_DRAGDROP, widget);
|
||||
|
||||
nsMouseEvent* mouseEvent = 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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NS_DRAGDROP_EXIT:
|
||||
// make sure to fire the enter and exit_synth events after the
|
||||
// NS_DRAGDROP_EXIT event, otherwise we'll clean up too early
|
||||
// clean up after ourselves. make sure we do this _after_ the event, else we'll
|
||||
// clean up too early!
|
||||
GenerateDragDropEnterExit(presContext, (nsGUIEvent*)aEvent);
|
||||
break;
|
||||
|
||||
@ -3562,8 +3176,6 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
||||
//The frame has changed but the content may not have. Check before dispatching to content
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
|
||||
targetContent, lastContent, mLastDragOverFrame);
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
|
||||
targetContent, lastContent, mLastDragOverFrame);
|
||||
}
|
||||
@ -3584,8 +3196,6 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIContent> lastContent;
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
|
||||
nsnull, lastContent, mLastDragOverFrame);
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
|
||||
nsnull, lastContent, mLastDragOverFrame);
|
||||
|
||||
@ -3611,7 +3221,8 @@ nsEventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
|
||||
nsWeakFrame& aTargetFrame)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsDragEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMsg, aEvent->widget);
|
||||
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;
|
||||
|
@ -60,7 +60,6 @@ class nsIDocShellTreeNode;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsIFocusController;
|
||||
class imgIContainer;
|
||||
class nsDOMDataTransfer;
|
||||
|
||||
// mac uses click-hold context menus, a holdover from 4.x
|
||||
#ifdef XP_MACOSX
|
||||
@ -319,38 +318,6 @@ protected:
|
||||
nsIFrame* inDownFrame ) ;
|
||||
void StopTrackingDragGesture ( ) ;
|
||||
void GenerateDragGesture ( nsPresContext* aPresContext, nsMouseEvent *aEvent ) ;
|
||||
|
||||
/**
|
||||
* Determine which node the drag should be targeted at.
|
||||
* This is either the node clicked when there is a selection, or, for HTML,
|
||||
* the element with a draggable property set to true.
|
||||
*
|
||||
* aSelectionTarget - target to check for selection
|
||||
* aDataTransfer - data transfer object that will contain the data to drag
|
||||
* aIsSelection - [out] set to true if a selection is being dragged
|
||||
* aTargetNode - [out] the draggable node, or null if there isn't one
|
||||
*/
|
||||
void DetermineDragTarget(nsPresContext* aPresContext,
|
||||
nsIContent* aSelectionTarget,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aIsSelection,
|
||||
nsIContent** aTargetNode);
|
||||
|
||||
/*
|
||||
* Perform the default handling for the dragstart/draggesture event and set up a
|
||||
* drag for aDataTransfer if it contains any data.
|
||||
*
|
||||
* aDragEvent - the dragstart/draggesture event
|
||||
* aDataTransfer - the data transfer that holds the data to be dragged
|
||||
* aDragTarget - the target of the drag
|
||||
* aIsSelection - true if a selection is being dragged
|
||||
*/
|
||||
void DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection);
|
||||
|
||||
PRBool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
|
||||
/**
|
||||
* Set the fields of aEvent to reflect the mouse position and modifier keys
|
||||
|
@ -61,8 +61,6 @@ _TEST_FILES = \
|
||||
test_bug412567.html \
|
||||
test_bug443985.html \
|
||||
test_bug447736.html \
|
||||
test_draggableprop.html \
|
||||
test_dragstart.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
@ -1,91 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests for the draggable property on HTML elements</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
|
||||
<span id="elem1">One</span>
|
||||
<span id="elem2" draggable="true">Two</span>
|
||||
<span id="elem3" draggable="">Three</span>
|
||||
<span id="elem4" draggable="false">Four</span>
|
||||
<span id="elem5" draggable="other">Five</span>
|
||||
|
||||
<img id="img1" src="../happy.png">
|
||||
<img id="img2" src="../happy.png" draggable="true">
|
||||
<img id="img3" src="../happy.png" draggable="">
|
||||
<img id="img4" src="../happy.png" draggable="false">
|
||||
<img id="img5" src="../happy.png" draggable="other">
|
||||
|
||||
<a id="a1">One</a>
|
||||
<a id="a2" draggable="true">Two</a>
|
||||
<a id="a3" draggable="">Three</a>
|
||||
<a id="a4" draggable="false">Four</a>
|
||||
<a id="a5" draggable="other">Five</a>
|
||||
|
||||
<a id="ahref1" href="http://www.mozilla.org">One</a>
|
||||
<a id="ahref2" href="http://www.mozilla.org" draggable="true">Two</a>
|
||||
<a id="ahref3" href="http://www.mozilla.org" draggable="">Three</a>
|
||||
<a id="ahref4" href="http://www.mozilla.org" draggable="false">Four</a>
|
||||
<a id="ahref5" href="http://www.mozilla.org" draggable="other">Five</a>
|
||||
|
||||
<script>
|
||||
function check()
|
||||
{
|
||||
try {
|
||||
checkElements(1, false, true, false, true);
|
||||
checkElements(2, true, true, true, true);
|
||||
checkElements(3, false, true, false, true);
|
||||
checkElements(4, false, false, false, false);
|
||||
checkElements(5, false, true, false, true);
|
||||
}
|
||||
catch (ex) {
|
||||
is("script error", ex, "fail");
|
||||
}
|
||||
}
|
||||
|
||||
function checkElements(idx, estate, istate, astate, ahrefstate)
|
||||
{
|
||||
checkElement("elem" + idx, estate, false);
|
||||
checkElement("img" + idx, istate, true);
|
||||
checkElement("a" + idx, astate, false);
|
||||
checkElement("ahref" + idx, ahrefstate, true);
|
||||
}
|
||||
|
||||
function checkElement(elemid, state, statedef)
|
||||
{
|
||||
var elem = document.getElementById(elemid);
|
||||
|
||||
is(elem.draggable, state, elemid + "-initial");
|
||||
elem.draggable = true;
|
||||
is(elem.draggable, true, elemid + "-true");
|
||||
elem.draggable = false;
|
||||
is(elem.draggable, false, elemid + "-false");
|
||||
|
||||
elem.setAttribute("draggable", "true");
|
||||
is(elem.draggable, true, elemid + "-attr-true");
|
||||
elem.setAttribute("draggable", "false");
|
||||
is(elem.draggable, false, elemid + "-attr-false");
|
||||
elem.setAttribute("draggable", "other");
|
||||
is(elem.draggable, statedef, elemid + "-attr-other");
|
||||
elem.setAttribute("draggable", "");
|
||||
is(elem.draggable, statedef, elemid + "-attr-empty");
|
||||
elem.removeAttribute("draggable");
|
||||
is(elem.draggable, statedef, elemid + "-attr-removed");
|
||||
}
|
||||
|
||||
check();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -1,526 +0,0 @@
|
||||
<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>
|
||||
|
||||
<!--
|
||||
This test checks the dragstart event and the DataTransfer object
|
||||
-->
|
||||
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gDragInfo;
|
||||
var gDataTransfer = null;
|
||||
|
||||
function runTests()
|
||||
{
|
||||
// first, create a selection and try dragging it
|
||||
var draggable = $("draggable");
|
||||
window.getSelection().selectAllChildren(draggable);
|
||||
synthesizeMouse(draggable, 6, 6, { type: "mousedown" });
|
||||
synthesizeMouse(draggable, 14, 14, { type: "mousemove" });
|
||||
|
||||
// the dragstart should have occured due to moving the mouse. gDataTransfer
|
||||
// caches the dataTransfer that was used, however it should now be empty and
|
||||
// be read only.
|
||||
ok(gDataTransfer instanceof DataTransfer, "DataTransfer after dragstart event");
|
||||
checkTypes(gDataTransfer, [], 0, "after dragstart event");
|
||||
|
||||
expectError(function() gDataTransfer.setData("text/plain", "Some Text"),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setData when read only");
|
||||
expectError(function() gDataTransfer.clearData("text/plain"),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "clearData when read only");
|
||||
expectError(function() gDataTransfer.mozSetDataAt("text/plain", "Some Text", 0),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setDataAt when read only");
|
||||
expectError(function() gDataTransfer.mozClearDataAt("text/plain", 0),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "clearDataAt when read only");
|
||||
expectError(function() gDataTransfer.setDragImage(draggable, 10, 10),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setDragImage when read only");
|
||||
expectError(function() gDataTransfer.addElement(draggable),
|
||||
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "addElement when read only");
|
||||
|
||||
// next, dragging links and images
|
||||
sendMouseEventsForDrag("link");
|
||||
sendMouseEventsForDrag("image");
|
||||
|
||||
// disable testing input dragging for now, as it doesn't seem to be testable
|
||||
// draggable = $("input");
|
||||
// draggable.setSelectionRange(0, 4);
|
||||
// synthesizeMouse(draggable, 8, 8, { type: "mousedown" });
|
||||
// synthesizeMouse(draggable, 15, 15, { type: "mousemove" });
|
||||
// sendMouseEventsForDrag("input");
|
||||
|
||||
// next, check if the draggable attribute can be used to adjust the drag target
|
||||
sendMouseEventsForDrag("dragtrue");
|
||||
ok(gDragInfo.itemCount == 0 && gDragInfo.types.length == 0 && gDragInfo.target == $("dragtrue"), "draggable true node");
|
||||
sendMouseEventsForDrag("spantrue");
|
||||
ok(gDragInfo.itemCount == 0 && gDragInfo.types.length == 0 && gDragInfo.target == $("dragtrue"), "draggable true child");
|
||||
sendMouseEventsForDrag("dragfalse");
|
||||
ok(gDragInfo.itemCount == 0 && gDragInfo.types.length == 0 && gDragInfo.target == $("dragfalse").firstChild,
|
||||
"draggable false node");
|
||||
sendMouseEventsForDrag("spanfalse");
|
||||
ok(gDragInfo.itemCount == 0 && gDragInfo.types.length == 0 && gDragInfo.target == $("spanfalse").firstChild,
|
||||
"draggable false child");
|
||||
|
||||
var evt = document.createEvent("dragevent");
|
||||
ok(evt instanceof DragEvent, "synthetic dragevent class")
|
||||
ok(evt instanceof MouseEvent, "synthetic event inherits from MouseEvent")
|
||||
evt.initDragEvent("dragstart", true, true, window, 1, null);
|
||||
$("synthetic").dispatchEvent(evt);
|
||||
|
||||
var evt = document.createEvent("dragevents");
|
||||
ok(evt instanceof DragEvent, "synthetic dragevents class")
|
||||
evt.initDragEvent("dragover", true, true, window, 0, null);
|
||||
$("synthetic2").dispatchEvent(evt);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function sendMouseEventsForDrag(nodeid)
|
||||
{
|
||||
gDragInfo = null;
|
||||
|
||||
var draggable = $(nodeid);
|
||||
synthesizeMouse(draggable, 3, 3, { type: "mousedown" });
|
||||
synthesizeMouse(draggable, 10, 10, { type: "mousemove" });
|
||||
}
|
||||
|
||||
function doDragStartSelection(event)
|
||||
{
|
||||
is(event.type, "dragstart", "dragstart event type");
|
||||
is(event.target, $("draggable").firstChild, "dragstart event target");
|
||||
is(event.bubbles, true, "dragstart event bubbles");
|
||||
is(event.cancelable, true, "dragstart event cancelable");
|
||||
|
||||
var dt = event.dataTransfer;
|
||||
ok(dt instanceof DataTransfer, "dataTransfer is DataTransfer");
|
||||
gDataTransfer = dt;
|
||||
|
||||
var types = dt.types;
|
||||
is(types instanceof DOMStringList, true, "initial types is a DOMStringList");
|
||||
checkTypes(dt, ["text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial selection");
|
||||
|
||||
is(dt.getData("text/plain"), "This is a draggable bit of text.", "initial selection text/plain");
|
||||
is(dt.getData("text/html"), "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>",
|
||||
"initial selection text/html");
|
||||
|
||||
// text/unicode and Text are available for compatibility. They retrieve the
|
||||
// text/plain data
|
||||
is(dt.getData("text/unicode"), "This is a draggable bit of text.", "initial selection text/unicode");
|
||||
is(dt.getData("Text"), "This is a draggable bit of text.", "initial selection Text");
|
||||
|
||||
is(dt.mozItemCount, 1, "initial selection item count");
|
||||
|
||||
dt.clearData("text/plain");
|
||||
dt.clearData("text/html");
|
||||
dt.clearData("text/_moz_htmlinfo");
|
||||
dt.clearData("text/_moz_htmlcontext");
|
||||
|
||||
test_DataTransfer(dt);
|
||||
}
|
||||
|
||||
function test_DataTransfer(dt)
|
||||
{
|
||||
is(dt.mozItemCount, 0, "empty itemCount");
|
||||
|
||||
var types = dt.types;
|
||||
is(types instanceof DOMStringList, true, "empty types is a DOMStringList");
|
||||
checkTypes(dt, [], 0, "empty");
|
||||
is(dt.getData("text/plain"), "", "empty data is empty");
|
||||
|
||||
// calling setDataAt requires an index that is 0 <= index <= dt.itemCount
|
||||
expectError(function() dt.mozSetDataAt("text/plain", "Some Text", 1),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "setDataAt index too high");
|
||||
|
||||
// because an exception occured, the data should not have been added
|
||||
is(dt.mozItemCount, 0, "empty setDataAt index too high itemCount");
|
||||
dt.getData("text/plain", "", "empty setDataAt index too high getData");
|
||||
|
||||
// if the type is '', do nothing, or return ''
|
||||
dt.setData("", "Invalid Type");
|
||||
is(dt.types.length, 0, "invalid type setData");
|
||||
is(dt.getData(""), "", "invalid type getData"),
|
||||
dt.mozSetDataAt("", "Invalid Type", 0);
|
||||
is(dt.types.length, 0, "invalid type setDataAt");
|
||||
is(dt.mozGetDataAt("", 0), null, "invalid type getDataAt"),
|
||||
|
||||
// similar with clearDataAt and getDataAt
|
||||
expectError(function() dt.mozGetDataAt("text/plain", 1),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "getDataAt index too high");
|
||||
expectError(function() dt.mozClearDataAt("text/plain", 1),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "clearDataAt index too high");
|
||||
|
||||
dt.setData("text/plain", "Sample Text");
|
||||
is(dt.mozItemCount, 1, "added plaintext itemCount");
|
||||
checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "added plaintext");
|
||||
|
||||
// after all those exceptions, the data should still be the same
|
||||
checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "added plaintext after exception");
|
||||
|
||||
// modifying the data associated with the format should give it the new value
|
||||
dt.setData("text/plain", "Modified Text");
|
||||
is(dt.mozItemCount, 1, "modified plaintext itemCount");
|
||||
checkOneDataItem(dt, ["text/plain"], ["Modified Text"], 0, "modified plaintext");
|
||||
|
||||
dt.setData("text/html", "<strong>Modified Text</strong>");
|
||||
is(dt.mozItemCount, 1, "modified html itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["Modified Text", "<strong>Modified Text</strong>"],
|
||||
0, "modified html");
|
||||
|
||||
// modifying data for a type that already exists should adjust it in place,
|
||||
// not reinsert it at the beginning
|
||||
dt.setData("text/plain", "New Text");
|
||||
is(dt.mozItemCount, 1, "modified text again itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["New Text", "<strong>Modified Text</strong>"],
|
||||
0, "modified text again");
|
||||
|
||||
var draggable = $("draggable");
|
||||
dt.setData("application/-moz-node", draggable);
|
||||
checkOneDataItem(dt, ["text/plain", "text/html", "application/-moz-node"],
|
||||
["New Text", "<strong>Modified Text</strong>", draggable],
|
||||
0, "added node");
|
||||
|
||||
dt.clearData(""); // null means clear all
|
||||
is(dt.mozItemCount, 0, "itemCount after clearData empty string");
|
||||
checkTypes(dt, [], 0, "empty after clearData empty string");
|
||||
|
||||
dt.setData("text/plain", 22);
|
||||
dt.setData("text/html", 5.6);
|
||||
dt.setData("text/xml", 5.6);
|
||||
checkTypes(dt, ["text/plain", "text/html", "text/xml"], ["22", "5.6", ""], 0, "add numeric and empty data");
|
||||
|
||||
dt.clearData(); // no argument means clear all
|
||||
is(dt.mozItemCount, 0, "itemCount after clearData no argument");
|
||||
checkTypes(dt, [], 0, "empty after clearData no argument");
|
||||
|
||||
// check 'Text' type which should convert into text/plain
|
||||
dt.setData("Text", "Sample Text");
|
||||
checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "set Text");
|
||||
is(dt.getData("Text"), "Sample Text", "getData Text");
|
||||
is(dt.mozGetDataAt("Text", 0), "Sample Text", "getDataAt Text");
|
||||
dt.setData("text/plain", "More Text");
|
||||
checkOneDataItem(dt, ["text/plain"], ["More Text"], 0, "set text/plain after set Text");
|
||||
|
||||
dt.mozClearDataAt("", 0); // null means clear all
|
||||
is(dt.mozItemCount, 0, "itemCount after clearDataAt empty string");
|
||||
checkTypes(dt, [], 0, "empty after clearDataAt empty string");
|
||||
|
||||
// check text/uri-list type
|
||||
dt.setData("text/uri-list", "http://www.mozilla.org");
|
||||
checkURL(dt, "http://www.mozilla.org", "http://www.mozilla.org", 0, "set text/uri-list");
|
||||
|
||||
// check URL type which should add text/uri-list data
|
||||
dt.setData("URL", "ftp://ftp.example.com");
|
||||
checkURL(dt, "ftp://ftp.example.com", "ftp://ftp.example.com", 0, "set URL");
|
||||
checkTypes(dt, ["text/uri-list"], ["ftp://ftp.example.com"], "url types");
|
||||
|
||||
// clearing text/uri-list data
|
||||
dt.clearData("text/uri-list");
|
||||
is(dt.mozItemCount, 0, "itemCount after clear url-list");
|
||||
is(dt.getData("text/uri-list"), "", "text/uri-list after clear url-list");
|
||||
is(dt.getData("URL"), "", "URL after clear url-list");
|
||||
|
||||
// check text/uri-list parsing
|
||||
dt.setData("text/uri-list", "#http://www.mozilla.org\nhttp://www.xulplanet.com\nhttp://www.example.com");
|
||||
checkURL(dt, "http://www.xulplanet.com",
|
||||
"#http://www.mozilla.org\nhttp://www.xulplanet.com\nhttp://www.example.com",
|
||||
0, "uri-list 3 lines");
|
||||
|
||||
dt.setData("text/uri-list", "#http://www.mozilla.org");
|
||||
is(dt.getData("URL"), "", "uri-list commented");
|
||||
dt.setData("text/uri-list", "#http://www.mozilla.org\n");
|
||||
is(dt.getData("URL"), "", "uri-list commented with newline");
|
||||
|
||||
// check that clearing the URL type also clears the text/uri-list type
|
||||
dt.clearData("URL");
|
||||
is(dt.getData("text/uri-list"), "", "clear URL");
|
||||
|
||||
dt.setData("text/uri-list", "#http://www.mozilla.org\n\n\n\n\n");
|
||||
is(dt.getData("URL"), "", "uri-list with blank lines");
|
||||
dt.setData("text/uri-list", "");
|
||||
is(dt.getData("URL"), "", "empty uri-list");
|
||||
dt.setData("text/uri-list", "#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n");
|
||||
is(dt.getData("URL"), "http://www.xulplanet.com", "uri-list mix");
|
||||
dt.setData("text/uri-list", "\nhttp://www.mozilla.org");
|
||||
is(dt.getData("URL"), "", "empty line to start uri-list");
|
||||
dt.setData("text/uri-list", " http://www.mozilla.org#anchor ");
|
||||
is(dt.getData("URL"), "http://www.mozilla.org#anchor", "uri-list with spaces and hash");
|
||||
|
||||
// ensure that setDataAt works the same way
|
||||
dt.mozSetDataAt("text/uri-list", "#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n", 0);
|
||||
checkURL(dt, "http://www.xulplanet.com",
|
||||
"#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n",
|
||||
0, "uri-list mix setDataAt");
|
||||
|
||||
// now test adding multiple items to be dragged using the setDataAt method
|
||||
dt.clearData();
|
||||
dt.mozSetDataAt("text/plain", "First Item", 0);
|
||||
dt.mozSetDataAt("text/plain", "Second Item", 1);
|
||||
expectError(function() dt.mozSetDataAt("text/plain", "Some Text", 3),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "setDataAt index too high with two items");
|
||||
is(dt.mozItemCount, 2, "setDataAt item itemCount");
|
||||
checkOneDataItem(dt, ["text/plain"], ["First Item"], 0, "setDataAt item at index 0");
|
||||
checkOneDataItem(dt, ["text/plain"], ["Second Item"], 1, "setDataAt item at index 1");
|
||||
|
||||
dt.mozSetDataAt("text/html", "<em>First Item</em>", 0);
|
||||
dt.mozSetDataAt("text/html", "<em>Second Item</em>", 1);
|
||||
is(dt.mozItemCount, 2, "setDataAt two types item itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "<em>First Item</em>"], 0, "setDataAt two types item at index 0");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["Second Item", "<em>Second Item</em>"], 1, "setDataAt two types item at index 1");
|
||||
|
||||
dt.mozSetDataAt("text/html", "<em>Changed First Item</em>", 0);
|
||||
dt.mozSetDataAt("text/plain", "Changed Second Item", 1);
|
||||
is(dt.mozItemCount, 2, "changed with setDataAt item itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "<em>Changed First Item</em>"], 0, "changed with setDataAt item at index 0");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["Changed Second Item", "<em>Second Item</em>"], 1, "changed with setDataAt item at index 1");
|
||||
|
||||
dt.setData("text/html", "Changed with setData");
|
||||
is(dt.mozItemCount, 2, "changed with setData");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "Changed with setData"], 0, "changed with setData item at index 0");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["Changed Second Item", "<em>Second Item</em>"], 1, "changed with setData item at index 1");
|
||||
|
||||
dt.mozSetDataAt("application/-moz-node", draggable, 2);
|
||||
is(dt.mozItemCount, 3, "setDataAt node itemCount");
|
||||
checkOneDataItem(dt, ["application/-moz-node"], [draggable], 2, "setDataAt node item at index 2");
|
||||
|
||||
dt.mozClearDataAt("text/html", 1);
|
||||
is(dt.mozItemCount, 3, "clearDataAt itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "Changed with setData"], 0, "clearDataAt item at index 0");
|
||||
checkOneDataItem(dt, ["text/plain"], ["Changed Second Item"], 1, "clearDataAt item at index 1");
|
||||
|
||||
dt.mozClearDataAt("text/plain", 1);
|
||||
is(dt.mozItemCount, 2, "clearDataAt last type itemCount");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "Changed with setData"], 0, "clearDataAt last type at index 0");
|
||||
checkOneDataItem(dt, ["application/-moz-node"], [draggable], 1, "clearDataAt last type item at index 2");
|
||||
expectError(function() dt.mozGetDataAt("text/plain", 2),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "getDataAt after item removed index too high");
|
||||
|
||||
dt.mozSetDataAt("text/unknown", "Unknown type", 2);
|
||||
dt.mozSetDataAt("text/unknown", "Unknown type", 1);
|
||||
is(dt.mozItemCount, 3, "add unknown type");
|
||||
checkOneDataItem(dt, ["application/-moz-node", "text/unknown"],
|
||||
[draggable, "Unknown type"], 1, "add unknown type item at index 1");
|
||||
checkOneDataItem(dt, ["text/unknown"], ["Unknown type"], 2, "add unknown type item at index 2");
|
||||
|
||||
dt.mozClearDataAt("", 1);
|
||||
is(dt.mozItemCount, 2, "clearDataAt empty string");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "Changed with setData"], 0, "clearDataAt empty string item at index 0");
|
||||
checkOneDataItem(dt, ["text/unknown"],
|
||||
["Unknown type"], 1, "clearDataAt empty string item at index 1");
|
||||
|
||||
// passing a format that doesn't exist to clearData or clearDataAt should just
|
||||
// do nothing
|
||||
dt.clearData("text/something");
|
||||
dt.mozClearDataAt("text/something", 1);
|
||||
is(dt.mozItemCount, 2, "clearData type that does not exist");
|
||||
checkOneDataItem(dt, ["text/plain", "text/html"],
|
||||
["First Item", "Changed with setData"], 0, "clearData type that does not exist item at index 0");
|
||||
checkOneDataItem(dt, ["text/unknown"],
|
||||
["Unknown type"], 1, "clearData type that does not exist item at index 1");
|
||||
|
||||
expectError(function() dt.mozClearDataAt("text/plain", 3),
|
||||
"NS_ERROR_DOM_INDEX_SIZE_ERR", "clearData index too high with two items");
|
||||
|
||||
// ensure that clearData() removes all data associated with the first item
|
||||
dt.clearData();
|
||||
is(dt.mozItemCount, 1, "clearData no argument with multiple items itemCount");
|
||||
checkOneDataItem(dt, ["text/unknown"],
|
||||
["Unknown type"], 0, "clearData no argument with multiple items item at index 1");
|
||||
|
||||
// remove tha remaining data
|
||||
dt.mozClearDataAt("", 0);
|
||||
is(dt.mozItemCount, 0, "all data cleared");
|
||||
|
||||
// now check the effectAllowed and dropEffect properties
|
||||
is(dt.dropEffect, "none", "initial dropEffect");
|
||||
is(dt.effectAllowed, "uninitialized", "initial effectAllowed");
|
||||
|
||||
["copy", "none", "link", "", "other", "copyMove", "all", "uninitialized", "move"].forEach(
|
||||
function (i) {
|
||||
dt.dropEffect = i;
|
||||
is(dt.dropEffect, i == "" || i == "other" || i == "copyMove" ||
|
||||
i == "all" || i == "uninitialized" ? "link" : i,
|
||||
"dropEffect set to " + i);
|
||||
is(dt.effectAllowed, "uninitialized", "effectAllowed not modified by dropEffect set to " + i);
|
||||
}
|
||||
);
|
||||
|
||||
["move", "copy", "link", "", "other", "moveCopy", "copyMove",
|
||||
"linkMove", "copyLink", "all", "uninitialized", "none"].forEach(
|
||||
function (i) {
|
||||
dt.effectAllowed = i;
|
||||
is(dt.dropEffect, "move", "dropEffect not modified by effectAllowed set to " + i);
|
||||
is(dt.effectAllowed, i == "" || i == "other" || i == "moveCopy" ? "link" : i,
|
||||
"effectAllowed set to " + i);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function doDragStartLink(event)
|
||||
{
|
||||
var dt = event.dataTransfer;
|
||||
checkTypes(dt, ["text/x-moz-url", "text/x-moz-url-data", "text/x-moz-url-desc", "text/uri-list",
|
||||
"text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial link");
|
||||
|
||||
is(dt.mozItemCount, 1, "initial link item count");
|
||||
is(dt.getData("text/uri-list"), "http://www.mozilla.org/", "link text/uri-list");
|
||||
is(dt.getData("text/plain"), "http://www.mozilla.org/", "link text/plain");
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function doDragStartImage(event)
|
||||
{
|
||||
var dataurl = $("image").src;
|
||||
|
||||
var dt = event.dataTransfer;
|
||||
checkTypes(dt, ["text/x-moz-url", "text/x-moz-url-data", "text/x-moz-url-desc", "text/uri-list",
|
||||
"text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial image");
|
||||
|
||||
is(dt.mozItemCount, 1, "initial image item count");
|
||||
is(dt.getData("text/uri-list"), dataurl, "image text/uri-list");
|
||||
is(dt.getData("text/plain"), dataurl, "image text/plain");
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function doDragStartInput(event)
|
||||
{
|
||||
var dt = event.dataTransfer;
|
||||
checkTypes(dt, ["text/plain"], 0, "initial input");
|
||||
|
||||
is(dt.mozItemCount, 1, "initial input item count");
|
||||
// is(dt.getData("text/plain"), "Text", "input text/plain");
|
||||
|
||||
// event.preventDefault();
|
||||
}
|
||||
|
||||
function doDragStartSynthetic(event)
|
||||
{
|
||||
is(event.type, "dragstart", "synthetic dragstart event type");
|
||||
return;
|
||||
var dt = event.dataTransfer;
|
||||
ok(dt instanceof DataTransfer, "synthetic dragstart dataTransfer is DataTransfer");
|
||||
|
||||
checkTypes(dt, [], 0, "synthetic dragstart");
|
||||
|
||||
is(event.detail, 1, "synthetic dragstart detail");
|
||||
|
||||
dt.setData("text/plain", "Text");
|
||||
is(dt.getData("text/plain"), "Text", "synthetic dragstart data is set after adding");
|
||||
}
|
||||
|
||||
function doDragOverSynthetic(event)
|
||||
{
|
||||
is(event.type, "dragover", "synthetic dragover event type");
|
||||
return;
|
||||
|
||||
var dt = event.dataTransfer;
|
||||
ok(dt instanceof DataTransfer, "synthetic dragover dataTransfer is DataTransfer");
|
||||
|
||||
checkTypes(dt, [], 0, "synthetic dragover");
|
||||
|
||||
dt.setData("text/plain", "Text");
|
||||
is(dt.getData("text/plain"), "Text", "synthetic dragover data is set after adding");
|
||||
}
|
||||
|
||||
function onDragStartDraggable(event)
|
||||
{
|
||||
var dt = event.dataTransfer;
|
||||
gDragInfo = { itemCount: dt.mozItemCount, types: dt.types, target: event.originalTarget };
|
||||
}
|
||||
|
||||
function checkOneDataItem(dt, expectedtypes, expecteddata, index, testid)
|
||||
{
|
||||
checkTypes(dt, expectedtypes, index, testid);
|
||||
for (var f = 0; f < expectedtypes.length; f++) {
|
||||
if (index == 0)
|
||||
is(dt.getData(expectedtypes[f]), expecteddata[f], testid + " getData " + expectedtypes[f]);
|
||||
is(dt.mozGetDataAt(expectedtypes[f], index), expecteddata[f] ? expecteddata[f] : null,
|
||||
testid + " getDataAt " + expectedtypes[f]);
|
||||
}
|
||||
}
|
||||
|
||||
function checkTypes(dt, expectedtypes, index, testid)
|
||||
{
|
||||
if (index == 0) {
|
||||
var types = dt.types;
|
||||
is(types.length, expectedtypes.length, testid + " types length");
|
||||
for (var f = 0; f < expectedtypes.length; f++) {
|
||||
is(types[f], expectedtypes[f], testid + " " + types[f] + " check");
|
||||
}
|
||||
}
|
||||
|
||||
types = dt.mozTypesAt(index);
|
||||
is(types.length, expectedtypes.length, testid + " typesAt length");
|
||||
for (var f = 0; f < expectedtypes.length; f++) {
|
||||
is(types[f], expectedtypes[f], testid + " " + types[f] + " at " + index + " check");
|
||||
}
|
||||
}
|
||||
|
||||
function checkURL(dt, url, fullurllist, index, testid)
|
||||
{
|
||||
is(dt.getData("text/uri-list"), fullurllist, testid + " text/uri-list");
|
||||
is(dt.getData("URL"), url, testid + " URL");
|
||||
is(dt.mozGetDataAt("text/uri-list", 0), fullurllist, testid + " text/uri-list");
|
||||
is(dt.mozGetDataAt("URL", 0), fullurllist, testid + " URL");
|
||||
}
|
||||
|
||||
function expectError(fn, eid, testid)
|
||||
{
|
||||
var error = "";
|
||||
try {
|
||||
fn();
|
||||
} catch (ex) {
|
||||
error = ex.name;
|
||||
}
|
||||
is(error, eid, testid + " causes exception " + eid);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body style="height: 300px; overflow: auto;" onload="setTimeout(runTests, 0)">
|
||||
|
||||
<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> bit of text.</div>
|
||||
|
||||
<a id="link" href="http://www.mozilla.org/" ondragstart="doDragStartLink(event)">mozilla.org</a>
|
||||
|
||||
<img id="image" 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"
|
||||
ondragstart="doDragStartImage(event)">
|
||||
|
||||
<input id="input" value="Text in a box" ondragstart="doDragStartInput(event)">
|
||||
|
||||
<div style="-moz-user-select: none;" ondragstart="onDragStartDraggable(event)">
|
||||
<div id="dragtrue" draggable="true">
|
||||
This is a <span id="spantrue">draggable</span> area.
|
||||
</div>
|
||||
<div id="dragfalse" draggable="false">
|
||||
This is a <span id="spanfalse">non-draggable</span> area.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--iframe src="http://www.mozilla.org" width="400" height="400"></iframe-->
|
||||
|
||||
<div id="synthetic" ondragstart="doDragStartSynthetic(event)">Synthetic Event Dispatch</div>
|
||||
<div id="synthetic2" ondragover="doDragOverSynthetic(event)">Synthetic Event Dispatch</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -856,22 +856,6 @@ nsGenericHTMLElement::SetSpellcheck(PRBool aSpellcheck)
|
||||
return SetAttrHelper(nsGkAtoms::spellcheck, NS_LITERAL_STRING("false"));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetDraggable(PRBool* aDraggable)
|
||||
{
|
||||
*aDraggable = AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
|
||||
nsGkAtoms::_true, eIgnoreCase);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::SetDraggable(PRBool aDraggable)
|
||||
{
|
||||
return SetAttrHelper(nsGkAtoms::draggable,
|
||||
aDraggable ? NS_LITERAL_STRING("true") :
|
||||
NS_LITERAL_STRING("false"));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericHTMLElement::InNavQuirksMode(nsIDocument* aDoc)
|
||||
{
|
||||
|
@ -145,17 +145,15 @@ public:
|
||||
virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
|
||||
virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
|
||||
nsresult ScrollIntoView(PRBool aTop);
|
||||
// Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck(),
|
||||
// SetSpellcheck(), and GetDraggable() such that classes that inherit interfaces
|
||||
// with those methods properly override them
|
||||
// Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck() and
|
||||
// SetSpellcheck() such that classes that inherit interfaces with those
|
||||
// methods properly override them
|
||||
NS_IMETHOD Focus();
|
||||
NS_IMETHOD Blur();
|
||||
NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
|
||||
NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
|
||||
NS_IMETHOD GetSpellcheck(PRBool* aSpellcheck);
|
||||
NS_IMETHOD SetSpellcheck(PRBool aSpellcheck);
|
||||
NS_IMETHOD GetDraggable(PRBool* aDraggable);
|
||||
NS_IMETHOD SetDraggable(PRBool aDraggable);
|
||||
nsresult GetContentEditable(nsAString &aContentEditable);
|
||||
nsresult SetContentEditable(const nsAString &aContentEditable);
|
||||
|
||||
|
@ -103,9 +103,6 @@ public:
|
||||
NS_IMETHOD LinkAdded() { return NS_OK; }
|
||||
NS_IMETHOD LinkRemoved() { return NS_OK; }
|
||||
|
||||
// override from nsGenericHTMLElement
|
||||
NS_IMETHOD GetDraggable(PRBool* aDraggable);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
@ -181,20 +178,6 @@ NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLAnchorElement, TabIndex, tabindex, 0)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Type, type)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, AccessKey, accesskey)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetDraggable(PRBool* aDraggable)
|
||||
{
|
||||
// links can be dragged as long as there is an href and the
|
||||
// draggable attribute isn't false
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
|
||||
*aDraggable = !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
|
||||
nsGkAtoms::_false, eIgnoreCase);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// no href, so just use the same behavior as other elements
|
||||
return nsGenericHTMLElement::GetDraggable(aDraggable);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -107,9 +107,6 @@ public:
|
||||
// nsIDOMNSHTMLImageElement
|
||||
NS_DECL_NSIDOMNSHTMLIMAGEELEMENT
|
||||
|
||||
// override from nsGenericHTMLElement
|
||||
NS_IMETHOD GetDraggable(PRBool* aDraggable);
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
|
||||
JSObject* aObj, PRUint32 argc, jsval* argv);
|
||||
@ -220,15 +217,6 @@ NS_IMPL_URI_ATTR(nsHTMLImageElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap)
|
||||
NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageElement::GetDraggable(PRBool* aDraggable)
|
||||
{
|
||||
// images may be dragged unless the draggable attribute is false
|
||||
*aDraggable = !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
|
||||
nsGkAtoms::_false, eIgnoreCase);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageElement::GetComplete(PRBool* aComplete)
|
||||
{
|
||||
|
@ -44,14 +44,11 @@
|
||||
|
||||
/*
|
||||
* 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 \
|
||||
{ /* 1A107271-1E26-419A-BCF1-0A4CF7A66B45 */ \
|
||||
0x1a107271, 0x1e26, 0x419a, \
|
||||
{0xbc, 0xf1, 0x0a, 0x4c, 0xf7, 0xa6, 0x6b, 0x45} }
|
||||
{ /* CD5186C4-228F-4413-AFD9-B65DAA105714 */ \
|
||||
0xcd5186c4, 0x228f, 0x4413, \
|
||||
{0xaf, 0xd9, 0xb6, 0x5d, 0xaa, 0x10, 0x57, 0x14} }
|
||||
|
||||
|
||||
|
||||
@ -132,11 +129,6 @@ public:
|
||||
* @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)
|
||||
|
@ -67,8 +67,6 @@ XPIDLSRCS = \
|
||||
nsIDOMKeyEvent.idl \
|
||||
nsIDOMMutationEvent.idl \
|
||||
nsIDOMNSUIEvent.idl \
|
||||
nsIDOMDragEvent.idl \
|
||||
nsIDOMDataTransfer.idl \
|
||||
nsIDOMPopupBlockedEvent.idl \
|
||||
nsIDOMBeforeUnloadEvent.idl \
|
||||
nsIDOMNSEventTarget.idl \
|
||||
|
@ -1,237 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(B5947DD0-8E86-4B9C-AA65-C86303EFCF94)]
|
||||
interface nsIDOMDataTransfer : nsISupports
|
||||
{
|
||||
/**
|
||||
* The actual effect that will be used, and should always be one of the
|
||||
* possible values of effectAllowed.
|
||||
*
|
||||
* For dragstart, drag and dragleave events, the dropEffect is initialized
|
||||
* to none. Any value assigned to the dropEffect will be set, but the value
|
||||
* isn't used for anything.
|
||||
*
|
||||
* For the dragenter and dragover events, the dropEffect will be initialized
|
||||
* based on what action the user is requesting. How this is determined is
|
||||
* platform specific, but typically the user can press modifier keys to
|
||||
* adjust which action is desired. Within an event handler for the dragenter
|
||||
* and dragover events, the dropEffect should be modified if the action the
|
||||
* user is requesting is not the one that is desired.
|
||||
*
|
||||
* For the drop and dragend events, the dropEffect will be initialized to
|
||||
* the action that was desired, which will be the value that the dropEffect
|
||||
* had after the last dragenter or dragover event.
|
||||
*
|
||||
* Possible values:
|
||||
* copy - a copy of the source item is made at the new location
|
||||
* move - an item is moved to a new location
|
||||
* link - a link is established to the source at the new location
|
||||
* none - the item may not be dropped
|
||||
*
|
||||
* Assigning any other value has no effect and retains the old value.
|
||||
*/
|
||||
attribute DOMString dropEffect;
|
||||
|
||||
/*
|
||||
* Specifies the effects that are allowed for this drag. You may set this in
|
||||
* the dragstart event to set the desired effects for the source, and within
|
||||
* the dragenter and dragover events to set the desired effects for the
|
||||
* target. The value is not used for other events.
|
||||
*
|
||||
* Possible values:
|
||||
* copy - a copy of the source item is made at the new location
|
||||
* move - an item is moved to a new location
|
||||
* link - a link is established to the source at the new location
|
||||
* copyLink, copyMove, linkMove, all - combinations of the above
|
||||
* none - the item may not be dropped
|
||||
* uninitialized - the default value when the effect has not been set,
|
||||
* equivalent to all.
|
||||
*
|
||||
* Assigning any other value has no effect and retains the old value.
|
||||
*/
|
||||
attribute DOMString effectAllowed;
|
||||
|
||||
/**
|
||||
* Holds a list of the format types of the data that is stored for the first
|
||||
* item, in the same order the data was added. An empty list will be
|
||||
* returned if no data was added.
|
||||
*/
|
||||
readonly attribute nsIDOMDOMStringList types;
|
||||
|
||||
/**
|
||||
* Remove the data associated with a given format. If format is empty or not
|
||||
* specified, the data associated with all formats is removed. If data for
|
||||
* the specified format does not exist, or the data transfer contains no
|
||||
* data, this method will have no effect.
|
||||
*/
|
||||
void clearData([optional] in DOMString format);
|
||||
|
||||
/**
|
||||
* Set the data for a given format. If data for the format does not exist,
|
||||
* it is added at the end, such that the last item in the types list will be
|
||||
* the new format. If data for the format already exists, the existing data
|
||||
* is replaced in the same position. That is, the order of the types list is
|
||||
* not changed.
|
||||
*
|
||||
* @throws NS_ERROR_NULL_POINTER if the data is null
|
||||
*/
|
||||
void setData(in DOMString format, in DOMString data);
|
||||
|
||||
/**
|
||||
* Retrieves the data for a given format, or an empty string if data for
|
||||
* that format does not exist or the data transfer contains no data.
|
||||
*/
|
||||
DOMString getData(in DOMString format);
|
||||
|
||||
/**
|
||||
* Set the image to be used for dragging if a custom one is desired. Most of
|
||||
* the time, this would not be set, as a default image is created from the
|
||||
* node that was dragged.
|
||||
*
|
||||
* If the node is an HTML img element, an HTML canvas element or a XUL image
|
||||
* element, the image data is used. Otherwise, image should be a visible
|
||||
* node and the drag image will be created from this. If image is null, any
|
||||
* custom drag image is cleared and the default is used instead.
|
||||
*
|
||||
* The coordinates specify the offset into the image where the mouse cursor
|
||||
* should be. To center the image for instance, use values that are half the
|
||||
* width and height.
|
||||
*
|
||||
* @param image a node to use
|
||||
* @param x the horizontal offset
|
||||
* @param y the vertical offset
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
void setDragImage(in nsIDOMElement image, in long x, in long y);
|
||||
|
||||
/*
|
||||
* Set the drag source. Usually you would not change this, but it will
|
||||
* affect which node the drag and dragend events are fired at. The
|
||||
* default target is the node that was dragged.
|
||||
*
|
||||
* @param element drag source to use
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
void addElement(in nsIDOMElement element);
|
||||
};
|
||||
|
||||
[scriptable, uuid(A884E56C-1678-4978-AD20-142EE94108F5)]
|
||||
interface nsIDOMNSDataTransfer : nsISupports
|
||||
{
|
||||
/*
|
||||
* Integer version of dropEffect, set to one of the constants in nsIDragService.
|
||||
*/
|
||||
[noscript] attribute unsigned long dropEffectInt;
|
||||
|
||||
/*
|
||||
* Integer version of effectAllowed, set to one or a combination of the
|
||||
* constants in nsIDragService.
|
||||
*/
|
||||
[noscript] attribute unsigned long effectAllowedInt;
|
||||
|
||||
/**
|
||||
* Creates a copy of the data transfer object
|
||||
*/
|
||||
[noscript] nsIDOMDataTransfer clone(in PRUint32 aEventType);
|
||||
|
||||
/**
|
||||
* The number of items being dragged.
|
||||
*/
|
||||
readonly attribute unsigned long mozItemCount;
|
||||
|
||||
/**
|
||||
* Holds a list of the format types of the data that is stored for an item
|
||||
* at the specified index. If the index is not in the range from 0 to
|
||||
* itemCount - 1, an empty string list is returned.
|
||||
*/
|
||||
nsIDOMDOMStringList mozTypesAt(in unsigned long index);
|
||||
|
||||
/**
|
||||
* Remove the data associated with the given format for an item at the
|
||||
* specified index. The index is in the range from zero to itemCount - 1.
|
||||
*
|
||||
* If the last format for the item is removed, the entire item is removed,
|
||||
* reducing the itemCount by one.
|
||||
*
|
||||
* If format is empty, then the data associated with all formats is removed.
|
||||
* If the format is not found, then this method has no effect.
|
||||
*
|
||||
* @param format the format to remove
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
void mozClearDataAt(in DOMString format, in unsigned long index);
|
||||
|
||||
/*
|
||||
* A data transfer may store multiple items, each at a given zero-based
|
||||
* index. setDataAt may only be called with an index argument less than
|
||||
* itemCount in which case an existing item is modified, or equal to
|
||||
* itemCount in which case a new item is added, and the itemCount is
|
||||
* incremented by one.
|
||||
*
|
||||
* Data should be added in order of preference, with the most specific
|
||||
* format added first and the least specific format added last. If data of
|
||||
* the given format already exists, it is replaced in the same position as
|
||||
* the old data.
|
||||
*
|
||||
* The data should be either a string, a primitive boolean or number type
|
||||
* (which will be converted into a string) or an nsISupports.
|
||||
*
|
||||
* @param format the format to add
|
||||
* @param data the data to add
|
||||
* @throws NS_ERROR_NULL_POINTER if the data is null
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater than itemCount
|
||||
* @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
|
||||
*/
|
||||
void mozSetDataAt(in DOMString format, in nsIVariant data, in unsigned long index);
|
||||
|
||||
/**
|
||||
* Retrieve the data associated with the given format for an item at the
|
||||
* specified index, or null if it does not exist. The index should be in the
|
||||
* range from zero to itemCount - 1.
|
||||
*
|
||||
* @param format the format of the data to look up
|
||||
* @returns the data of the given format, or null if it doesn't exist.
|
||||
* @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
|
||||
*/
|
||||
nsIVariant mozGetDataAt(in DOMString format, in unsigned long index);
|
||||
};
|
@ -1,63 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "domstubs.idl"
|
||||
#include "nsIDOMMouseEvent.idl"
|
||||
|
||||
interface nsIDOMAbstractView;
|
||||
interface nsIDOMDataTransfer;
|
||||
|
||||
[scriptable, uuid(18FEEFD7-A461-4865-BCF1-4DC8A2F30584)]
|
||||
interface nsIDOMDragEvent : nsIDOMMouseEvent
|
||||
{
|
||||
readonly attribute nsIDOMDataTransfer dataTransfer;
|
||||
|
||||
void initDragEvent(in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean cancelableArg,
|
||||
in nsIDOMAbstractView aView,
|
||||
in PRInt32 aDetail,
|
||||
in nsIDOMDataTransfer aDataTransfer);
|
||||
|
||||
void initDragEventNS(in DOMString namespaceURIArg,
|
||||
in DOMString typeArg,
|
||||
in boolean canBubbleArg,
|
||||
in boolean cancelableArg,
|
||||
in nsIDOMAbstractView aView,
|
||||
in PRInt32 aDetail,
|
||||
in nsIDOMDataTransfer aDataTransfer);
|
||||
};
|
@ -38,7 +38,7 @@
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(7F142F9A-FBA7-4949-93D6-CF08A974AC51)]
|
||||
[scriptable, uuid(5D090306-86AA-43F8-A78F-7346084DA4C5)]
|
||||
interface nsIDOMNSHTMLElement : nsISupports
|
||||
{
|
||||
readonly attribute long offsetTop;
|
||||
@ -52,9 +52,6 @@ interface nsIDOMNSHTMLElement : nsISupports
|
||||
|
||||
attribute DOMString contentEditable;
|
||||
|
||||
// for WHAT-WG drag and drop
|
||||
attribute boolean draggable;
|
||||
|
||||
void blur();
|
||||
void focus();
|
||||
|
||||
|
@ -84,7 +84,6 @@ enum nsDOMClassInfoID {
|
||||
eDOMClassInfo_UIEvent_id,
|
||||
eDOMClassInfo_MouseEvent_id,
|
||||
eDOMClassInfo_MouseScrollEvent_id,
|
||||
eDOMClassInfo_DragEvent_id,
|
||||
eDOMClassInfo_KeyboardEvent_id,
|
||||
eDOMClassInfo_PopupBlockedEvent_id,
|
||||
|
||||
@ -449,8 +448,6 @@ enum nsDOMClassInfoID {
|
||||
// DOM Traversal NodeIterator class
|
||||
eDOMClassInfo_NodeIterator_id,
|
||||
|
||||
eDOMClassInfo_DataTransfer_id,
|
||||
|
||||
// This one better be the last one in this list
|
||||
eDOMClassInfoIDCount
|
||||
};
|
||||
|
@ -235,7 +235,6 @@
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMMouseScrollEvent.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsIDOMCommandEvent.h"
|
||||
#include "nsIDOMPopupBlockedEvent.h"
|
||||
#include "nsIDOMBeforeUnloadEvent.h"
|
||||
@ -450,9 +449,6 @@
|
||||
#include "nsIDOMStorageEvent.h"
|
||||
#include "nsIDOMToString.h"
|
||||
|
||||
// Drag and drop
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
|
||||
// Offline includes
|
||||
#include "nsIDOMLoadStatusList.h"
|
||||
#include "nsIDOMLoadStatus.h"
|
||||
@ -657,8 +653,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MouseScrollEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(DragEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
|
||||
@ -1287,11 +1281,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
// DOM Traversal NodeIterator class
|
||||
NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
// data transfer for drag and drop
|
||||
NS_DEFINE_CLASSINFO_DATA(DataTransfer, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
};
|
||||
|
||||
// Objects that shuld be constructable through |new Name();|
|
||||
@ -2133,11 +2122,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DragEvent, nsIDOMDragEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDragEvent)
|
||||
DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(HTMLDocument, nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLDocument)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLDocument)
|
||||
@ -3509,7 +3493,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLAudioElement)
|
||||
DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#endif
|
||||
DOM_CLASSINFO_MAP_BEGIN(ProgressEvent, nsIDOMProgressEvent)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMProgressEvent)
|
||||
@ -3522,11 +3505,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DataTransfer, nsIDOMDataTransfer)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataTransfer)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSDataTransfer)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
{
|
||||
PRUint32 i = NS_ARRAY_LENGTH(sClassInfoData);
|
||||
|
@ -253,6 +253,95 @@ nsEditorHookUtils::GetHookEnumeratorFromDocument(nsIDOMDocument *aDoc,
|
||||
return hookObj->GetHookEnumerator(aResult);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aDragEvent)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool canDrag = PR_TRUE;
|
||||
nsresult hookres = override->AllowStartDrag(aDragEvent, &canDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookres), "hook failure in AllowStartDrag");
|
||||
if (!canDrag)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsITransferable *aTrans)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool canInvokeDrag = PR_TRUE;
|
||||
nsresult hookResult = override->OnCopyOrDrag(aEvent, aTrans, &canInvokeDrag);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in OnCopyOrDrag");
|
||||
if (!canInvokeDrag)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoAllowDropHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsIDragSession *aSession)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator));
|
||||
if (!enumerator)
|
||||
return PR_TRUE;
|
||||
|
||||
PRBool hasMoreHooks = PR_FALSE;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks)
|
||||
{
|
||||
nsCOMPtr<nsISupports> isupp;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp))))
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIClipboardDragDropHooks> override = do_QueryInterface(isupp);
|
||||
if (override)
|
||||
{
|
||||
PRBool allowDrop = PR_TRUE;
|
||||
nsresult hookResult = override->AllowDrop(aEvent, aSession, &allowDrop);
|
||||
NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in AllowDrop");
|
||||
if (!allowDrop)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsEditorHookUtils::DoInsertionHook(nsIDOMDocument *aDoc, nsIDOMEvent *aDropEvent,
|
||||
nsITransferable *aTrans)
|
||||
|
@ -274,6 +274,11 @@ class nsISimpleEnumerator;
|
||||
class nsEditorHookUtils
|
||||
{
|
||||
public:
|
||||
static PRBool DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent);
|
||||
static PRBool DoDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsITransferable *aTrans);
|
||||
static PRBool DoAllowDropHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsIDragSession *aSession);
|
||||
static PRBool DoInsertionHook(nsIDOMDocument *aDoc, nsIDOMEvent *aEvent,
|
||||
nsITransferable *aTrans);
|
||||
private:
|
||||
|
@ -1497,6 +1497,8 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
// transferable hooks here
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
if (!nsEditorHookUtils::DoAllowDropHook(domdoc, aDropEvent, dragSession))
|
||||
return NS_OK;
|
||||
|
||||
// find out if we have our internal html flavor on the clipboard. We don't want to mess
|
||||
// around with cfhtml if we do.
|
||||
|
@ -570,6 +570,13 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent)
|
||||
}
|
||||
|
||||
PRBool canDrop = CanDrop(aDragEvent);
|
||||
if (canDrop)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
mEditor->GetDocument(getter_AddRefs(domdoc));
|
||||
canDrop = nsEditorHookUtils::DoAllowDropHook(domdoc, aDragEvent, dragSession);
|
||||
}
|
||||
|
||||
dragSession->SetCanDrop(canDrop);
|
||||
|
||||
// We need to consume the event to prevent the browser's
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
@ -164,6 +163,10 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
rv = GetDocument(getter_AddRefs(destdomdoc));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// transferable hooks
|
||||
if (!nsEditorHookUtils::DoAllowDropHook(destdomdoc, aDropEvent, dragSession))
|
||||
return NS_OK;
|
||||
|
||||
// Get the nsITransferable interface for getting the data from the drop
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = PrepareTransferable(getter_AddRefs(trans));
|
||||
@ -298,6 +301,9 @@ NS_IMETHODIMP nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!trans) return NS_OK; // NS_ERROR_FAILURE; Should we fail?
|
||||
|
||||
if (!nsEditorHookUtils::DoInsertionHook(destdomdoc, aDropEvent, trans))
|
||||
return NS_OK;
|
||||
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
rv = InsertTextFromTransferable(trans, newSelectionParent, newSelectionOffset, deleteSelection);
|
||||
@ -357,7 +363,13 @@ NS_IMETHODIMP nsPlaintextEditor::CanDrag(nsIDOMEvent *aDragEvent, PRBool *aCanDr
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!*aCanDrag) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
*aCanDrag = nsEditorHookUtils::DoAllowDragHook(domdoc, aDragEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
||||
@ -387,6 +399,8 @@ NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
||||
// check our transferable hooks (if any)
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
GetDocument(getter_AddRefs(domdoc));
|
||||
if (!nsEditorHookUtils::DoDragHook(domdoc, aDragEvent, trans))
|
||||
return NS_OK;
|
||||
|
||||
/* invoke drag */
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
@ -403,9 +417,9 @@ NS_IMETHODIMP nsPlaintextEditor::DoDrag(nsIDOMEvent *aDragEvent)
|
||||
// in some cases we'll want to cut rather than copy... hmmmmm...
|
||||
flags = nsIDragService::DRAGDROP_ACTION_COPY + nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
|
||||
nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aDragEvent));
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(aDragEvent));
|
||||
rv = dragService->InvokeDragSessionWithSelection(selection, transferableArray,
|
||||
flags, dragEvent, nsnull);
|
||||
flags, mouseEvent);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
aDragEvent->StopPropagation();
|
||||
|
@ -626,8 +626,7 @@ nsPoint
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(const nsEvent* aEvent, nsIFrame* aFrame)
|
||||
{
|
||||
if (!aEvent || (aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
aEvent->eventStructType != NS_DRAG_EVENT))
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT))
|
||||
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
const nsGUIEvent* GUIEvent = static_cast<const nsGUIEvent*>(aEvent);
|
||||
@ -670,8 +669,7 @@ nsLayoutUtils::GetEventCoordinatesForNearestView(nsEvent* aEvent,
|
||||
nsIView** aView)
|
||||
{
|
||||
if (!aEvent || (aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
aEvent->eventStructType != NS_DRAG_EVENT))
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT))
|
||||
return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
nsGUIEvent* GUIEvent = static_cast<nsGUIEvent*>(aEvent);
|
||||
|
@ -46,9 +46,8 @@ interface nsITreeView;
|
||||
interface nsITreeSelection;
|
||||
interface nsITreeColumn;
|
||||
interface nsITreeColumns;
|
||||
interface nsIScriptableRegion;
|
||||
|
||||
[scriptable, uuid(64BA5199-C4F4-4498-BBDC-F8E4C369086C)]
|
||||
[scriptable, uuid(a264f607-9d90-469e-b770-1ae7284fde05)]
|
||||
interface nsITreeBoxObject : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -88,11 +87,6 @@ interface nsITreeBoxObject : nsISupports
|
||||
*/
|
||||
readonly attribute long horizontalPosition;
|
||||
|
||||
/**
|
||||
* Return the region for the visible parts of the selection, in device pixels.
|
||||
*/
|
||||
readonly attribute nsIScriptableRegion selectionRegion;
|
||||
|
||||
/**
|
||||
* Get the index of the first visible row.
|
||||
*/
|
||||
|
@ -642,48 +642,6 @@ nsTreeBodyFrame::GetPageLength(PRInt32 *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeBodyFrame::GetSelectionRegion(nsIScriptableRegion **aRegion)
|
||||
{
|
||||
*aRegion = nsnull;
|
||||
|
||||
nsCOMPtr<nsITreeSelection> selection;
|
||||
mView->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_TRUE(selection, NS_OK);
|
||||
|
||||
nsCOMPtr<nsIScriptableRegion> region = do_CreateInstance("@mozilla.org/gfx/region;1");
|
||||
NS_ENSURE_TRUE(region, NS_ERROR_FAILURE);
|
||||
region->Init();
|
||||
|
||||
nsRefPtr<nsPresContext> presContext = PresContext();
|
||||
nsRect rect = mRect;
|
||||
rect.ScaleRoundOut(1.0 / presContext->AppUnitsPerCSSPixel());
|
||||
|
||||
nsIFrame* rootFrame = presContext->PresShell()->GetRootFrame();
|
||||
nsPoint origin = GetOffsetTo(rootFrame);
|
||||
|
||||
// iterate through the visible rows and add the selected ones to the
|
||||
// drag region
|
||||
PRInt32 x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
|
||||
PRInt32 y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);
|
||||
PRInt32 top = y;
|
||||
PRInt32 end = GetLastVisibleRow();
|
||||
PRInt32 rowHeight = nsPresContext::AppUnitsToIntCSSPixels(mRowHeight);
|
||||
for (PRInt32 i = mTopRowIndex; i <= end; i++) {
|
||||
PRBool isSelected;
|
||||
selection->IsSelected(i, &isSelected);
|
||||
if (isSelected)
|
||||
region->UnionRect(x, y, rect.width, rowHeight);
|
||||
y += rowHeight;
|
||||
}
|
||||
|
||||
// clip to the tree boundary in case one row extends past it
|
||||
region->IntersectRect(x, top, rect.width, rect.height);
|
||||
|
||||
NS_ADDREF(*aRegion = region);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeBodyFrame::Invalidate()
|
||||
{
|
||||
@ -2612,8 +2570,6 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
mSlots->mDragSession->GetDragAction(&mSlots->mDragAction);
|
||||
else
|
||||
mSlots->mDragAction = 0;
|
||||
mSlots->mDropRow = -1;
|
||||
mSlots->mDropOrient = -1;
|
||||
}
|
||||
else if (aEvent->message == NS_DRAGDROP_OVER) {
|
||||
// The mouse is hovering over this tree. If we determine things are
|
||||
@ -2738,9 +2694,6 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
mView->Drop(mSlots->mDropRow, mSlots->mDropOrient);
|
||||
mSlots->mDropRow = -1;
|
||||
mSlots->mDropOrient = -1;
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault; // already handled the drop
|
||||
}
|
||||
else if (aEvent->message == NS_DRAGDROP_EXIT) {
|
||||
// this event was meant for another frame, so ignore it
|
||||
@ -2755,11 +2708,11 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
else
|
||||
mSlots->mDropAllowed = PR_FALSE;
|
||||
mSlots->mDropRow = -1;
|
||||
mSlots->mDropOrient = -1;
|
||||
mSlots->mDragSession = nsnull;
|
||||
mSlots->mScrollLines = 0;
|
||||
// If a drop is occuring, the exit event will fire just before the drop
|
||||
// event, so don't reset mDropRow or mDropOrient as these fields are used
|
||||
// by the drop event.
|
||||
|
||||
if (mSlots->mTimer) {
|
||||
mSlots->mTimer->Cancel();
|
||||
mSlots->mTimer = nsnull;
|
||||
|
@ -294,15 +294,6 @@ NS_IMETHODIMP nsTreeBoxObject::GetPageLength(PRInt32 *aPageLength)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTreeBoxObject::GetSelectionRegion(nsIScriptableRegion **aRegion)
|
||||
{
|
||||
*aRegion = nsnull;
|
||||
nsITreeBoxObject* body = GetTreeBody();
|
||||
if (body)
|
||||
return body->GetSelectionRegion(aRegion);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTreeBoxObject::EnsureRowIsVisible(PRInt32 aRow)
|
||||
{
|
||||
|
@ -208,9 +208,8 @@ function synthesizeMouse(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
||||
var clickCount = aEvent.clickCount || 1;
|
||||
var modifiers = _parseModifiers(aEvent);
|
||||
|
||||
var rect = aTarget.getBoundingClientRect();
|
||||
var left = rect.left;
|
||||
var top = rect.top;
|
||||
var left = aTarget.boxObject.x;
|
||||
var top = aTarget.boxObject.y;
|
||||
|
||||
if (aEvent.type) {
|
||||
utils.sendMouseEvent(aEvent.type, left + aOffsetX, top + aOffsetY, button, clickCount, modifiers);
|
||||
|
@ -37,9 +37,6 @@
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
// non-strings need some non-zero value used for their data length
|
||||
const kNonStringDataLength = 4;
|
||||
|
||||
/**
|
||||
* nsTransferable - a wrapper for nsITransferable that simplifies
|
||||
* javascript clipboard and drag&drop. for use in
|
||||
@ -270,15 +267,17 @@ function FlavourData(aData, aLength, aFlavour)
|
||||
FlavourData.prototype = {
|
||||
get data ()
|
||||
{
|
||||
if (this.flavour &&
|
||||
this.flavour.dataIIDKey != "nsISupportsString")
|
||||
if (this.flavour &&
|
||||
this.flavour.dataIIDKey != "nsISupportsString" )
|
||||
return this.supports.QueryInterface(Components.interfaces[this.flavour.dataIIDKey]);
|
||||
|
||||
var supports = this.supports;
|
||||
if (supports instanceof Components.interfaces.nsISupportsString)
|
||||
return supports.data.substring(0, this.contentLength/2);
|
||||
else {
|
||||
var unicode = this.supports.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
if (unicode)
|
||||
return unicode.data.substring(0, this.contentLength/2);
|
||||
|
||||
return supports;
|
||||
return this.supports;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,7 +298,7 @@ var transferUtils = {
|
||||
case "text/unicode":
|
||||
return aData.replace(/^\s+|\s+$/g, "");
|
||||
case "text/x-moz-url":
|
||||
return ((aData instanceof Components.interfaces.nsISupportsString) ? aData.toString() : aData).split("\n")[0];
|
||||
return aData.toString().split("\n")[0];
|
||||
case "application/x-moz-file":
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
@ -382,33 +381,63 @@ var nsDragAndDrop = {
|
||||
|
||||
if (!transferData.data) return;
|
||||
transferData = transferData.data;
|
||||
|
||||
var transArray = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
|
||||
var dt = aEvent.dataTransfer;
|
||||
var count = 0;
|
||||
do {
|
||||
var tds = transferData._XferID == "TransferData"
|
||||
? transferData
|
||||
: transferData.dataList[count]
|
||||
for (var i = 0; i < tds.dataList.length; ++i)
|
||||
{
|
||||
var currData = tds.dataList[i];
|
||||
var currFlavour = currData.flavour.contentType;
|
||||
var value = currData.supports;
|
||||
if (value instanceof Components.interfaces.nsISupportsString)
|
||||
value = value.toString();
|
||||
dt.mozSetDataAt(currFlavour, value, count);
|
||||
var region = null;
|
||||
if (aEvent.originalTarget.localName == "treechildren") {
|
||||
// let's build the drag region
|
||||
var tree = aEvent.originalTarget.parentNode;
|
||||
try {
|
||||
region = Components.classes["@mozilla.org/gfx/region;1"].createInstance(Components.interfaces.nsIScriptableRegion);
|
||||
region.init();
|
||||
var obo = tree.treeBoxObject;
|
||||
var bo = obo.treeBody.boxObject;
|
||||
var sel= obo.view.selection;
|
||||
|
||||
var rowX = bo.x;
|
||||
var rowY = bo.y;
|
||||
var rowHeight = obo.rowHeight;
|
||||
var rowWidth = bo.width;
|
||||
|
||||
//add a rectangle for each visible selected row
|
||||
for (var i = obo.getFirstVisibleRow(); i <= obo.getLastVisibleRow(); i ++)
|
||||
{
|
||||
if (sel.isSelected(i))
|
||||
region.unionRect(rowX, rowY, rowWidth, rowHeight);
|
||||
rowY = rowY + rowHeight;
|
||||
}
|
||||
|
||||
//and finally, clip the result to be sure we don't spill over...
|
||||
region.intersectRect(bo.x, bo.y, bo.width, bo.height);
|
||||
} catch(ex) {
|
||||
dump("Error while building selection region: " + ex + "\n");
|
||||
region = null;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
do
|
||||
{
|
||||
var trans = nsTransferable.set(transferData._XferID == "TransferData"
|
||||
? transferData
|
||||
: transferData.dataList[count++]);
|
||||
transArray.AppendElement(trans.QueryInterface(Components.interfaces.nsISupports));
|
||||
}
|
||||
while (transferData._XferID == "TransferDataSet" &&
|
||||
count < transferData.dataList.length);
|
||||
|
||||
dt.effectAllowed = "all";
|
||||
// a drag targeted at a tree should instead use the treechildren so that
|
||||
// the current selection is used as the drag feedback
|
||||
dt.addElement(aEvent.originalTarget.localName == "treechildren" ?
|
||||
aEvent.originalTarget : aEvent.target);
|
||||
|
||||
try {
|
||||
this.mDragService.invokeDragSessionWithImage(aEvent.target, transArray,
|
||||
region, dragAction.action,
|
||||
null, 0, 0, aEvent);
|
||||
}
|
||||
catch(ex) {
|
||||
// this could be because the user pressed escape to
|
||||
// cancel the drag. even if it's not, there's not much
|
||||
// we can do, so be silent.
|
||||
}
|
||||
aEvent.stopPropagation();
|
||||
},
|
||||
|
||||
@ -438,7 +467,6 @@ var nsDragAndDrop = {
|
||||
flavourSet.flavourTable[flavour],
|
||||
this.mDragSession);
|
||||
aEvent.stopPropagation();
|
||||
aEvent.preventDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -463,37 +491,14 @@ var nsDragAndDrop = {
|
||||
return;
|
||||
if (!this.checkCanDrop(aEvent, aDragDropObserver))
|
||||
return;
|
||||
|
||||
var flavourSet = aDragDropObserver.getSupportedFlavours();
|
||||
|
||||
var dt = aEvent.dataTransfer;
|
||||
var dataArray = [];
|
||||
var count = dt.mozItemCount;
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var types = dt.mozTypesAt(i);
|
||||
for (var j = 0; j < types.length; ++j) {
|
||||
var type = types[j];
|
||||
// dataTransfer uses text/plain but older code used text/unicode, so
|
||||
// switch this for compatibility
|
||||
if (type == "text/plain")
|
||||
type = "text/unicode";
|
||||
if (type in flavourSet.flavourTable) {
|
||||
var data = dt.mozGetDataAt(type, i);
|
||||
if (data) {
|
||||
var length = (typeof data == "string") ? data.length : kNonStringDataLength;
|
||||
dataArray[i] = FlavourToXfer(data, length, flavourSet.flavourTable[type]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.mDragSession.canDrop) {
|
||||
var flavourSet = aDragDropObserver.getSupportedFlavours();
|
||||
var transferData = nsTransferable.get(flavourSet, this.getDragData, true);
|
||||
// hand over to the client to respond to dropped data
|
||||
var multiple = "canHandleMultipleItems" in aDragDropObserver && aDragDropObserver.canHandleMultipleItems;
|
||||
var dropData = multiple ? transferData : transferData.first.first;
|
||||
aDragDropObserver.onDrop(aEvent, dropData, this.mDragSession);
|
||||
}
|
||||
|
||||
var transferData = new TransferDataSet(dataArray)
|
||||
|
||||
// hand over to the client to respond to dropped data
|
||||
var multiple = "canHandleMultipleItems" in aDragDropObserver && aDragDropObserver.canHandleMultipleItems;
|
||||
var dropData = multiple ? transferData : transferData.first.first;
|
||||
aDragDropObserver.onDrop(aEvent, dropData, this.mDragSession);
|
||||
aEvent.stopPropagation();
|
||||
},
|
||||
|
||||
@ -534,6 +539,31 @@ var nsDragAndDrop = {
|
||||
if ("onDragEnter" in aDragDropObserver)
|
||||
aDragDropObserver.onDragEnter(aEvent, this.mDragSession);
|
||||
},
|
||||
|
||||
/**
|
||||
* nsISupportsArray getDragData (Object aFlavourList)
|
||||
*
|
||||
* Creates a nsISupportsArray of all droppable items for the given
|
||||
* set of supported flavours.
|
||||
*
|
||||
* @param FlavourSet aFlavourSet
|
||||
* formatted flavour list.
|
||||
**/
|
||||
getDragData: function (aFlavourSet)
|
||||
{
|
||||
var supportsArray = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
|
||||
for (var i = 0; i < nsDragAndDrop.mDragSession.numDropItems; ++i)
|
||||
{
|
||||
var trans = nsTransferable.createTransferable();
|
||||
for (var j = 0; j < aFlavourSet.flavours.length; ++j)
|
||||
trans.addDataFlavor(aFlavourSet.flavours[j].contentType);
|
||||
nsDragAndDrop.mDragSession.getData(trans, i);
|
||||
supportsArray.AppendElement(trans);
|
||||
}
|
||||
return supportsArray;
|
||||
},
|
||||
|
||||
/**
|
||||
* Boolean checkCanDrop (DOMEvent aEvent, Object aDragDropObserver) ;
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsTArray.h"
|
||||
@ -107,7 +106,6 @@ class nsHashKey;
|
||||
#ifdef MOZ_MEDIA
|
||||
#define NS_MEDIA_EVENT 34
|
||||
#endif // MOZ_MEDIA
|
||||
#define NS_DRAG_EVENT 35
|
||||
|
||||
// These flags are sort of a mess. They're sort of shared between event
|
||||
// listener flags and event flags, but only some of them. You've been
|
||||
@ -250,19 +248,17 @@ class nsHashKey;
|
||||
#define NS_FOCUS_CONTENT (NS_FOCUS_EVENT_START)
|
||||
#define NS_BLUR_CONTENT (NS_FOCUS_EVENT_START + 1)
|
||||
|
||||
|
||||
#define NS_DRAGDROP_EVENT_START 1400
|
||||
#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_DRAGDROP (NS_DRAGDROP_EVENT_START + 3)
|
||||
#define NS_DRAGDROP_DROP (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
|
||||
@ -682,20 +678,6 @@ public:
|
||||
enum contextType { eNormal, eContextMenuKey };
|
||||
enum exitType { eChild, eTopLevel };
|
||||
|
||||
protected:
|
||||
nsMouseEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w,
|
||||
PRUint8 structType, reasonType aReason)
|
||||
: nsMouseEvent_base(isTrusted, msg, w, structType),
|
||||
acceptActivation(PR_FALSE), reason(aReason), context(eNormal),
|
||||
exit(eChild), clickCount(0)
|
||||
{
|
||||
if (msg == NS_MOUSE_MOVE) {
|
||||
flags |= NS_EVENT_FLAG_CANT_CANCEL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
nsMouseEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w,
|
||||
reasonType aReason, contextType aContext = eNormal)
|
||||
: nsMouseEvent_base(isTrusted, msg, w, NS_MOUSE_EVENT),
|
||||
@ -728,26 +710,6 @@ public:
|
||||
PRUint32 clickCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* Drag event
|
||||
*/
|
||||
|
||||
class nsDragEvent : public nsMouseEvent
|
||||
{
|
||||
public:
|
||||
nsDragEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||
: nsMouseEvent(isTrusted, msg, w, NS_DRAG_EVENT, eReal)
|
||||
{
|
||||
if (msg == NS_DRAGDROP_EXIT_SYNTH ||
|
||||
msg == NS_DRAGDROP_LEAVE_SYNTH ||
|
||||
msg == NS_DRAGDROP_END) {
|
||||
flags |= NS_EVENT_FLAG_CANT_CANCEL;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> dataTransfer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessible event
|
||||
*/
|
||||
@ -1097,13 +1059,10 @@ enum nsDragDropEventStatus {
|
||||
(((evnt)->message == NS_DRAGDROP_ENTER) || \
|
||||
((evnt)->message == NS_DRAGDROP_OVER) || \
|
||||
((evnt)->message == NS_DRAGDROP_EXIT) || \
|
||||
((evnt)->message == NS_DRAGDROP_DRAGDROP) || \
|
||||
((evnt)->message == NS_DRAGDROP_GESTURE) || \
|
||||
((evnt)->message == NS_DRAGDROP_DRAG) || \
|
||||
((evnt)->message == NS_DRAGDROP_END) || \
|
||||
((evnt)->message == NS_DRAGDROP_START) || \
|
||||
((evnt)->message == NS_DRAGDROP_DROP) || \
|
||||
((evnt)->message == NS_DRAGDROP_LEAVE_SYNTH))
|
||||
((evnt)->message == NS_DRAGDROP_GESTURE) || \
|
||||
((evnt)->message == NS_DRAGDROP_OVER_SYNTH) || \
|
||||
((evnt)->message == NS_DRAGDROP_EXIT_SYNTH))
|
||||
|
||||
#define NS_IS_KEY_EVENT(evnt) \
|
||||
(((evnt)->message == NS_KEY_DOWN) || \
|
||||
|
@ -44,18 +44,16 @@
|
||||
|
||||
|
||||
interface nsIDOMNode;
|
||||
interface nsIDOMDragEvent;
|
||||
interface nsIDOMDataTransfer;
|
||||
interface nsIDOMMouseEvent;
|
||||
interface nsISelection;
|
||||
|
||||
[scriptable, uuid(82B58ADA-F490-4C3D-B737-1057C4F1D052)]
|
||||
[scriptable, uuid(034c44a4-604b-44a2-9205-676d5135f359)]
|
||||
interface nsIDragService : nsISupports
|
||||
{
|
||||
const long DRAGDROP_ACTION_NONE = 0;
|
||||
const long DRAGDROP_ACTION_COPY = 1;
|
||||
const long DRAGDROP_ACTION_MOVE = 2;
|
||||
const long DRAGDROP_ACTION_LINK = 4;
|
||||
const long DRAGDROP_ACTION_UNINITIALIZED = 64;
|
||||
|
||||
/**
|
||||
* Starts a modal drag session with an array of transaferables
|
||||
@ -100,8 +98,7 @@ interface nsIDragService : nsISupports
|
||||
in nsIDOMNode aImage,
|
||||
in long aImageX,
|
||||
in long aImageY,
|
||||
in nsIDOMDragEvent aDragEvent,
|
||||
in nsIDOMDataTransfer aDataTransfer);
|
||||
in nsIDOMMouseEvent aDragEvent);
|
||||
|
||||
/**
|
||||
* Start a modal drag session using the selection as the drag image.
|
||||
@ -111,8 +108,7 @@ interface nsIDragService : nsISupports
|
||||
void invokeDragSessionWithSelection(in nsISelection aSelection,
|
||||
in nsISupportsArray aTransferableArray,
|
||||
in unsigned long aActionType,
|
||||
in nsIDOMDragEvent aDragEvent,
|
||||
in nsIDOMDataTransfer aDataTransfer);
|
||||
in nsIDOMMouseEvent aDragEvent);
|
||||
|
||||
/**
|
||||
* Returns the current Drag Session
|
||||
|
@ -51,9 +51,8 @@ native nsSize (nsSize);
|
||||
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMNode;
|
||||
interface nsIDOMDataTransfer;
|
||||
|
||||
[scriptable, uuid(15860D52-FE2C-4DDD-AC50-9C23E24916C4)]
|
||||
[scriptable, uuid(CBA22C53-FCCE-11d2-96D4-0060B0FB9956)]
|
||||
interface nsIDragSession : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -91,11 +90,6 @@ interface nsIDragSession : nsISupports
|
||||
*/
|
||||
readonly attribute nsIDOMNode sourceNode;
|
||||
|
||||
/**
|
||||
* The data transfer object for the current drag.
|
||||
*/
|
||||
attribute nsIDOMDataTransfer dataTransfer;
|
||||
|
||||
/**
|
||||
* Get data from a Drag&Drop. Can be called while the drag is in process
|
||||
* or after the drop has completed.
|
||||
|
@ -1937,7 +1937,7 @@ bool nsWindow::CallMethod(MethodInfo *info)
|
||||
{
|
||||
NS_ASSERTION(info->nArgs == 4, "Wrong number of arguments to CallMethod");
|
||||
|
||||
nsDragEvent event(PR_TRUE, (int32) info->args[0], this);
|
||||
nsMouseEvent event(PR_TRUE, (int32) info->args[0], this, nsMouseEvent::eReal);
|
||||
nsPoint point(((int32 *)info->args)[1], ((int32 *)info->args)[2]);
|
||||
InitEvent (event, &point);
|
||||
uint32 mod = (uint32) info->args[3];
|
||||
|
@ -5753,14 +5753,8 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
||||
// We make the assumption that the dragOver handlers have correctly set
|
||||
// the |canDrop| property of the Drag Session.
|
||||
PRBool canDrop = PR_FALSE;
|
||||
if (!NS_SUCCEEDED(dragSession->GetCanDrop(&canDrop)) || !canDrop) {
|
||||
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||
dragSession->GetSourceNode(getter_AddRefs(sourceNode));
|
||||
if (!sourceNode) {
|
||||
mDragService->EndDragSession(PR_FALSE);
|
||||
}
|
||||
if (!NS_SUCCEEDED(dragSession->GetCanDrop(&canDrop)) || !canDrop)
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int modifierFlags = [[NSApp currentEvent] modifierFlags];
|
||||
@ -5776,7 +5770,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
||||
}
|
||||
|
||||
// set up gecko event
|
||||
nsDragEvent geckoEvent(PR_TRUE, aMessage, nsnull);
|
||||
nsMouseEvent geckoEvent(PR_TRUE, aMessage, nsnull, nsMouseEvent::eReal);
|
||||
[self convertGenericCocoaEvent:nil toGeckoEvent:&geckoEvent];
|
||||
|
||||
// Use our own coordinates in the gecko event.
|
||||
@ -5790,8 +5784,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
|
||||
if (!mGeckoChild)
|
||||
return YES;
|
||||
|
||||
if ((aMessage == NS_DRAGDROP_EXIT || aMessage == NS_DRAGDROP_DROP) &&
|
||||
dragSession) {
|
||||
if (aMessage == NS_DRAGDROP_EXIT && dragSession) {
|
||||
nsCOMPtr<nsIDOMNode> sourceNode;
|
||||
dragSession->GetSourceNode(getter_AddRefs(sourceNode));
|
||||
if (!sourceNode) {
|
||||
|
@ -571,9 +571,8 @@ nsDragService::EndDragSession(PRBool aDoneDrag)
|
||||
mNativeDragEvent = nil;
|
||||
}
|
||||
|
||||
nsresult rv = nsBaseDragService::EndDragSession(aDoneDrag);
|
||||
mDataItems = nsnull;
|
||||
return rv;
|
||||
return nsBaseDragService::EndDragSession(aDoneDrag);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
@ -2920,7 +2920,8 @@ nsWindow::OnDragMotionEvent(GtkWidget *aWidget,
|
||||
|
||||
dragService->FireDragEventAtSource(NS_DRAGDROP_DRAG);
|
||||
|
||||
nsDragEvent event(PR_TRUE, NS_DRAGDROP_OVER, innerMostWidget);
|
||||
nsMouseEvent event(PR_TRUE, NS_DRAGDROP_OVER, innerMostWidget,
|
||||
nsMouseEvent::eReal);
|
||||
|
||||
InitDragEvent(event);
|
||||
|
||||
@ -3028,7 +3029,8 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
|
||||
// re-validate the drag target and then we do the drop. The events
|
||||
// look the same except for the type.
|
||||
|
||||
nsDragEvent event(PR_TRUE, NS_DRAGDROP_OVER, innerMostWidget);
|
||||
nsMouseEvent event(PR_TRUE, NS_DRAGDROP_OVER, innerMostWidget,
|
||||
nsMouseEvent::eReal);
|
||||
|
||||
InitDragEvent(event);
|
||||
|
||||
@ -3099,7 +3101,7 @@ nsWindow::OnDragLeave(void)
|
||||
{
|
||||
LOG(("nsWindow::OnDragLeave(%p)\n", this));
|
||||
|
||||
nsDragEvent event(PR_TRUE, NS_DRAGDROP_EXIT, this);
|
||||
nsMouseEvent event(PR_TRUE, NS_DRAGDROP_EXIT, this, nsMouseEvent::eReal);
|
||||
|
||||
nsEventStatus status;
|
||||
DispatchEvent(&event, status);
|
||||
@ -3139,7 +3141,7 @@ nsWindow::OnDragEnter(nscoord aX, nscoord aY)
|
||||
dragService->StartDragSession();
|
||||
}
|
||||
|
||||
nsDragEvent event(PR_TRUE, NS_DRAGDROP_ENTER, this);
|
||||
nsMouseEvent event(PR_TRUE, NS_DRAGDROP_ENTER, this, nsMouseEvent::eReal);
|
||||
|
||||
event.refPoint.x = aX;
|
||||
event.refPoint.y = aY;
|
||||
@ -5126,7 +5128,7 @@ theme_changed_cb (GtkSettings *settings, GParamSpec *pspec, nsWindow *data)
|
||||
// These are all of our drag and drop operations
|
||||
|
||||
void
|
||||
nsWindow::InitDragEvent(nsDragEvent &aEvent)
|
||||
nsWindow::InitDragEvent(nsMouseEvent &aEvent)
|
||||
{
|
||||
// set the keyboard modifiers
|
||||
gint x, y;
|
||||
@ -5143,7 +5145,7 @@ nsWindow::InitDragEvent(nsDragEvent &aEvent)
|
||||
// and what the source is offering.
|
||||
|
||||
void
|
||||
nsWindow::UpdateDragStatus(nsDragEvent &aEvent,
|
||||
nsWindow::UpdateDragStatus(nsMouseEvent &aEvent,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIDragService *aDragService)
|
||||
{
|
||||
|
@ -442,8 +442,8 @@ private:
|
||||
// all of our DND stuff
|
||||
// this is the last window that had a drag event happen on it.
|
||||
static nsWindow *mLastDragMotionWindow;
|
||||
void InitDragEvent (nsDragEvent &aEvent);
|
||||
void UpdateDragStatus (nsDragEvent &aEvent,
|
||||
void InitDragEvent (nsMouseEvent &aEvent);
|
||||
void UpdateDragStatus (nsMouseEvent &aEvent,
|
||||
GdkDragContext *aDragContext,
|
||||
nsIDragService *aDragService);
|
||||
|
||||
|
@ -527,7 +527,7 @@ PRBool nsWindow::DispatchCommandEvent(PRUint32 aEventCommand)
|
||||
|
||||
PRBool nsWindow::DispatchDragDropEvent(PRUint32 aMsg)
|
||||
{
|
||||
nsDragEvent event(PR_TRUE, aMsg, this);
|
||||
nsMouseEvent event(PR_TRUE, aMsg, this, nsMouseEvent::eReal);
|
||||
InitEvent(event);
|
||||
|
||||
event.isShift = WinIsKeyDown(VK_SHIFT);
|
||||
|
@ -1242,7 +1242,7 @@ void nsWidget::ProcessDrag( PhEvent_t *event, PRUint32 aEventType, PhPoint_t *po
|
||||
|
||||
void nsWidget::DispatchDragDropEvent( PhEvent_t *phevent, PRUint32 aEventType, PhPoint_t *pos ) {
|
||||
nsEventStatus status;
|
||||
nsDragEvent event(PR_TRUE, 0, nsnull);
|
||||
nsMouseEvent event(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
|
||||
|
||||
InitEvent( event, aEventType );
|
||||
|
||||
|
@ -193,7 +193,7 @@ void
|
||||
nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
|
||||
{
|
||||
nsEventStatus status;
|
||||
nsDragEvent event(PR_TRUE, aEventType, mWindow);
|
||||
nsMouseEvent event(PR_TRUE, aEventType, mWindow, nsMouseEvent::eReal);
|
||||
|
||||
nsWindow * win = static_cast<nsWindow *>(mWindow);
|
||||
win->InitEvent(event);
|
||||
|
@ -55,11 +55,10 @@
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIImage.h"
|
||||
@ -196,21 +195,6 @@ nsBaseDragService::IsDataFlavorSupported(const char *aDataFlavor,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragService::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
|
||||
{
|
||||
*aDataTransfer = mDataTransfer;
|
||||
NS_IF_ADDREF(*aDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragService::SetDataTransfer(nsIDOMDataTransfer* aDataTransfer)
|
||||
{
|
||||
mDataTransfer = aDataTransfer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsBaseDragService::InvokeDragSession(nsIDOMNode *aDOMNode,
|
||||
@ -255,14 +239,11 @@ nsBaseDragService::InvokeDragSessionWithImage(nsIDOMNode* aDOMNode,
|
||||
PRUint32 aActionType,
|
||||
nsIDOMNode* aImage,
|
||||
PRInt32 aImageX, PRInt32 aImageY,
|
||||
nsIDOMDragEvent* aDragEvent,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
nsIDOMMouseEvent* aDragEvent)
|
||||
{
|
||||
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aDataTransfer, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
||||
|
||||
mDataTransfer = aDataTransfer;
|
||||
mSelection = nsnull;
|
||||
mHasImage = PR_TRUE;
|
||||
mImage = aImage;
|
||||
@ -279,14 +260,12 @@ NS_IMETHODIMP
|
||||
nsBaseDragService::InvokeDragSessionWithSelection(nsISelection* aSelection,
|
||||
nsISupportsArray* aTransferableArray,
|
||||
PRUint32 aActionType,
|
||||
nsIDOMDragEvent* aDragEvent,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
nsIDOMMouseEvent* aDragEvent)
|
||||
{
|
||||
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aDragEvent, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(mSuppressLevel == 0, NS_ERROR_FAILURE);
|
||||
|
||||
mDataTransfer = aDataTransfer;
|
||||
mSelection = aSelection;
|
||||
mHasImage = PR_TRUE;
|
||||
mImage = nsnull;
|
||||
@ -297,8 +276,6 @@ nsBaseDragService::InvokeDragSessionWithSelection(nsISelection* aSelection,
|
||||
aDragEvent->GetScreenY(&mScreenY);
|
||||
|
||||
// just get the focused node from the selection
|
||||
// XXXndeakin this should actually be the deepest node that contains both
|
||||
// endpoints of the selection
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
aSelection->GetFocusNode(getter_AddRefs(node));
|
||||
|
||||
@ -352,7 +329,6 @@ nsBaseDragService::EndDragSession(PRBool aDoneDrag)
|
||||
mSourceDocument = nsnull;
|
||||
mSourceNode = nsnull;
|
||||
mSelection = nsnull;
|
||||
mDataTransfer = nsnull;
|
||||
mHasImage = PR_FALSE;
|
||||
mImage = nsnull;
|
||||
mImageX = 0;
|
||||
@ -372,7 +348,7 @@ nsBaseDragService::FireDragEventAtSource(PRUint32 aMsg)
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
if (presShell) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsDragEvent event(PR_TRUE, aMsg, nsnull);
|
||||
nsMouseEvent event(PR_TRUE, aMsg, nsnull, nsMouseEvent::eReal);
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mSourceNode);
|
||||
return presShell->HandleDOMEventWithTarget(content, &event, &status);
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
@ -132,7 +131,6 @@ protected:
|
||||
nsCOMPtr<nsIDOMNode> mSourceNode;
|
||||
nsCOMPtr<nsIDOMDocument> mSourceDocument; // the document at the drag source. will be null
|
||||
// if it came from outside the app.
|
||||
nsCOMPtr<nsIDOMDataTransfer> mDataTransfer;
|
||||
|
||||
// used to determine the image to appear on the cursor while dragging
|
||||
nsCOMPtr<nsIDOMNode> mImage;
|
||||
|
@ -134,8 +134,6 @@ nsPrimitiveHelpers :: CreateDataFromPrimitive ( const char* aFlavor, nsISupports
|
||||
if ( !aDataBuff )
|
||||
return;
|
||||
|
||||
*aDataBuff = nsnull;
|
||||
|
||||
if ( strcmp(aFlavor,kTextMime) == 0 ) {
|
||||
nsCOMPtr<nsISupportsCString> plainText ( do_QueryInterface(aPrimitive) );
|
||||
if ( plainText ) {
|
||||
|
@ -19,8 +19,8 @@ toolkit.jar:
|
||||
content/global/nsTreeController.js (resources/content/nsTreeController.js)
|
||||
content/global/nsTreeSorting.js (resources/content/nsTreeSorting.js)
|
||||
content/global/nsClipboard.js (resources/content/nsClipboard.js)
|
||||
* content/global/nsDragAndDrop.js (/toolkit/content/nsDragAndDrop.js)
|
||||
* content/global/nsTransferable.js (/toolkit/content/nsDragAndDrop.js)
|
||||
content/global/nsDragAndDrop.js (resources/content/nsDragAndDrop.js)
|
||||
content/global/nsTransferable.js (resources/content/nsDragAndDrop.js)
|
||||
content/global/nsUserSettings.js (resources/content/nsUserSettings.js)
|
||||
content/global/xul.css (resources/content/xul.css)
|
||||
* content/global/inlineSpellCheckUI.js (/toolkit/content/inlineSpellCheckUI.js)
|
||||
|
Loading…
Reference in New Issue
Block a user