diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js index 8f1b254868d..30e1c45d1b8 100644 --- a/browser/base/content/pageinfo/pageInfo.js +++ b/browser/base/content/pageinfo/pageInfo.js @@ -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 diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 26a9f66d87e..9438c691090 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -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 GetDragSession(); - /** * Return true if aURI is a local file URI (i.e. file://). */ diff --git a/content/base/src/nsContentAreaDragDrop.cpp b/content/base/src/nsContentAreaDragDrop.cpp index 8bc117e1ebf..8f3c1a38a94 100644 --- a/content/base/src/nsContentAreaDragDrop.cpp +++ b/content/base/src/nsContentAreaDragDrop.cpp @@ -45,7 +45,6 @@ #include "nsString.h" // Interfaces needed to be included -#include "nsIVariant.h" #include "nsIDOMNSUIEvent.h" #include "nsIDOMUIEvent.h" #include "nsISelection.h" @@ -53,7 +52,7 @@ #include "nsIDOMNodeList.h" #include "nsIDOMEvent.h" #include "nsIDOMNSEvent.h" -#include "nsIDOMDragEvent.h" +#include "nsIDOMMouseEvent.h" #include "nsIDOMAbstractView.h" #include "nsPIDOMWindow.h" #include "nsIDOMDocument.h" @@ -74,6 +73,8 @@ #include "nsNetUtil.h" #include "nsIFile.h" #include "nsIWebNavigation.h" +#include "nsIClipboardDragDropHooks.h" +#include "nsIClipboardDragDropHookList.h" #include "nsIDocShell.h" #include "nsIContent.h" #include "nsIImageLoadingContent.h" @@ -83,7 +84,6 @@ #include "nsIImage.h" #include "nsIDocument.h" #include "nsIScriptSecurityManager.h" -#include "nsIPrincipal.h" #include "nsIPresShell.h" #include "nsPresContext.h" #include "nsIDocShellTreeItem.h" @@ -95,7 +95,6 @@ #include "nsIMIMEService.h" #include "imgIRequest.h" #include "nsContentCID.h" -#include "nsDOMDataTransfer.h" #include "nsISelectionController.h" #include "nsFrameSelection.h" #include "nsIDOMEventTarget.h" @@ -115,6 +114,7 @@ NS_INTERFACE_MAP_BEGIN(nsContentAreaDragDrop) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDragListener) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMDragListener) NS_INTERFACE_MAP_ENTRY(nsIDOMDragListener) + NS_INTERFACE_MAP_ENTRY(nsIFlavorDataProvider) NS_INTERFACE_MAP_ENTRY(nsIDragDropHandler) NS_INTERFACE_MAP_END @@ -122,45 +122,35 @@ NS_INTERFACE_MAP_END class NS_STACK_CLASS nsTransferableFactory { public: - nsTransferableFactory(nsIDOMWindow* aWindow, - nsIContent* aTarget, - nsIContent* aSelectionTargetNode, - PRBool aIsAltKeyPressed); - nsresult Produce(nsDOMDataTransfer* aDataTransfer, - PRBool* aCanDrag, - PRBool* aDragSelection, - nsIContent** aDragNode); + nsTransferableFactory(nsIDOMEvent* inMouseEvent, + nsIFlavorDataProvider *inFlavorDataProvider); + nsresult Produce(PRBool *aDragSelection, nsITransferable** outTrans); private: - void AddString(nsDOMDataTransfer* aDataTransfer, - const nsAString& aFlavor, - const nsAString& aData, - nsIPrincipal* aPrincipal); - nsresult AddStringsToDataTransfer(nsIContent* aDragNode, - nsDOMDataTransfer* aDataTransfer); + nsresult ConvertStringsToTransferable(nsITransferable** outTrans); static nsresult GetDraggableSelectionData(nsISelection* inSelection, - nsIContent* inRealTargetNode, - nsIContent **outImageOrLinkNode, + nsIDOMNode* inRealTargetNode, + nsIDOMNode **outImageOrLinkNode, PRBool* outDragSelectedText); - static already_AddRefed FindParentLinkNode(nsIContent* inNode); - static void GetAnchorURL(nsIContent* inNode, nsAString& outURL); - static void GetNodeString(nsIContent* inNode, nsAString & outNodeString); + static already_AddRefed FindParentLinkNode(nsIDOMNode* inNode); + static void GetAnchorURL(nsIDOMNode* inNode, nsAString& outURL); + static void GetNodeString(nsIDOMNode* inNode, nsAString & outNodeString); static void CreateLinkText(const nsAString& inURL, const nsAString & inText, nsAString& outLinkText); static void GetSelectedLink(nsISelection* inSelection, - nsIContent **outLinkNode); + nsIDOMNode **outLinkNode); // if inNode is null, use the selection from the window static nsresult SerializeNodeOrSelection(nsIDOMWindow* inWindow, - nsIContent* inNode, + nsIDOMNode* inNode, nsAString& outResultString, nsAString& outHTMLContext, nsAString& outHTMLInfo); - nsCOMPtr mWindow; - nsCOMPtr mTarget; - nsCOMPtr mSelectionTargetNode; - PRPackedBool mIsAltKeyPressed; + PRBool mInstanceAlreadyUsed; + + nsCOMPtr mMouseEvent; + nsCOMPtr mFlavorDataProvider; nsString mUrlString; nsString mImageSourceString; @@ -302,53 +292,91 @@ nsContentAreaDragDrop::DragOver(nsIDOMEvent* inEvent) // early. This avoids loading a URL dragged from the content // area into the very same content area (which is almost never // the desired action). + nsCOMPtr dragService = + do_GetService("@mozilla.org/widget/dragservice;1"); + if (!dragService) + return NS_ERROR_FAILURE; - nsCOMPtr session = nsContentUtils::GetDragSession(); - NS_ENSURE_TRUE(session, NS_OK); + nsCOMPtr session; + dragService->GetCurrentSession(getter_AddRefs(session)); - PRBool dropAllowed = PR_TRUE; + if (session) { + // if the client has provided an override callback, check if we + // the drop is allowed. If it allows it, we should still protect + // against dropping w/in the same document. + PRBool dropAllowed = PR_TRUE; + nsCOMPtr enumerator; + GetHookEnumeratorFromEvent(inEvent, getter_AddRefs(enumerator)); - nsCOMPtr sourceDoc; - session->GetSourceDocument(getter_AddRefs(sourceDoc)); - nsCOMPtr eventDoc; - GetEventDocument(inEvent, getter_AddRefs(eventDoc)); + if (enumerator) { + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) + && hasMoreHooks) { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) { + break; + } - if (sourceDoc == eventDoc) { // common case - dropAllowed = PR_FALSE; - } else if (sourceDoc && eventDoc) { - // dig deeper - // XXXbz we need better ways to get from a document to the docshell! - nsCOMPtr sourceDocument(do_QueryInterface(sourceDoc)); - nsCOMPtr eventDocument(do_QueryInterface(eventDoc)); - NS_ASSERTION(sourceDocument, "Confused document object"); - NS_ASSERTION(eventDocument, "Confused document object"); + nsCOMPtr override = + do_QueryInterface(isupp); - nsPIDOMWindow* sourceWindow = sourceDocument->GetWindow(); - nsPIDOMWindow* eventWindow = eventDocument->GetWindow(); + if (override) { +#ifdef DEBUG + nsresult hookResult = +#endif + override->AllowDrop(inEvent, session, &dropAllowed); + NS_ASSERTION(NS_SUCCEEDED(hookResult), "hook failure in AllowDrop"); - if (sourceWindow && eventWindow) { - nsCOMPtr sourceShell = - do_QueryInterface(sourceWindow->GetDocShell()); - nsCOMPtr eventShell = - do_QueryInterface(eventWindow->GetDocShell()); - - if (sourceShell && eventShell) { - // Whew. Almost there. Get the roots that are of the same type - // (otherwise we'll always end up with the root docshell for the - // window, and drag/drop from chrom to content won't work). - nsCOMPtr sourceRoot; - nsCOMPtr eventRoot; - sourceShell->GetSameTypeRootTreeItem(getter_AddRefs(sourceRoot)); - eventShell->GetSameTypeRootTreeItem(getter_AddRefs(eventRoot)); - - if (sourceRoot && sourceRoot == eventRoot) { - dropAllowed = PR_FALSE; + if (!dropAllowed) { + break; + } } } } + + nsCOMPtr sourceDoc; + session->GetSourceDocument(getter_AddRefs(sourceDoc)); + nsCOMPtr eventDoc; + GetEventDocument(inEvent, getter_AddRefs(eventDoc)); + + if (sourceDoc == eventDoc) { // common case + dropAllowed = PR_FALSE; + } else if (sourceDoc && eventDoc) { + // dig deeper + // XXXbz we need better ways to get from a document to the docshell! + nsCOMPtr sourceDocument(do_QueryInterface(sourceDoc)); + nsCOMPtr eventDocument(do_QueryInterface(eventDoc)); + NS_ASSERTION(sourceDocument, "Confused document object"); + NS_ASSERTION(eventDocument, "Confused document object"); + + nsPIDOMWindow* sourceWindow = sourceDocument->GetWindow(); + nsPIDOMWindow* eventWindow = eventDocument->GetWindow(); + + if (sourceWindow && eventWindow) { + nsCOMPtr sourceShell = + do_QueryInterface(sourceWindow->GetDocShell()); + nsCOMPtr eventShell = + do_QueryInterface(eventWindow->GetDocShell()); + + if (sourceShell && eventShell) { + // Whew. Almost there. Get the roots that are of the same type + // (otherwise we'll always end up with the root docshell for the + // window, and drag/drop from chrom to content won't work). + nsCOMPtr sourceRoot; + nsCOMPtr eventRoot; + sourceShell->GetSameTypeRootTreeItem(getter_AddRefs(sourceRoot)); + eventShell->GetSameTypeRootTreeItem(getter_AddRefs(eventRoot)); + + if (sourceRoot && sourceRoot == eventRoot) { + dropAllowed = PR_FALSE; + } + } + } + } + + session->SetCanDrop(dropAllowed); } - session->SetCanDrop(dropAllowed); return NS_OK; } @@ -469,8 +497,17 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent) // pull the transferable out of the drag service. at the moment, we // only care about the first item of the drag. We don't allow // dropping multiple items into a content area. - nsCOMPtr session = nsContentUtils::GetDragSession(); - NS_ENSURE_TRUE(session, NS_OK); + nsCOMPtr dragService = + do_GetService("@mozilla.org/widget/dragservice;1"); + if (!dragService) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr session; + dragService->GetCurrentSession(getter_AddRefs(session)); + if (!session) { + return NS_ERROR_FAILURE; + } nsCOMPtr trans = do_CreateInstance("@mozilla.org/widget/transferable;1"); @@ -488,6 +525,35 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent) nsresult rv = session->GetData(trans, 0); if (NS_SUCCEEDED(rv)) { + // if the client has provided an override callback, call it. It may + // still return that we should continue processing. + nsCOMPtr enumerator; + GetHookEnumeratorFromEvent(inMouseEvent, getter_AddRefs(enumerator)); + + if (enumerator) { + PRBool actionCanceled = PR_TRUE; + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) + && hasMoreHooks) { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + nsCOMPtr override = + do_QueryInterface(isupp); + + if (override) { +#ifdef DEBUG + nsresult hookResult = +#endif + override->OnPasteOrDrop(inMouseEvent, trans, &actionCanceled); + NS_ASSERTION(NS_SUCCEEDED(hookResult), + "hook failure in OnPasteOrDrop"); + if (!actionCanceled) + return NS_OK; + } + } + } + nsXPIDLCString flavor; nsCOMPtr dataWrapper; PRUint32 dataLen = 0; @@ -599,34 +665,166 @@ nsContentAreaDragDrop::GetEventDocument(nsIDOMEvent* inEvent, } } +nsresult +nsContentAreaDragDrop::GetHookEnumeratorFromEvent(nsIDOMEvent* inEvent, + nsISimpleEnumerator **outEnumerator) +{ + *outEnumerator = nsnull; + + nsCOMPtr domdoc; + GetEventDocument(inEvent, getter_AddRefs(domdoc)); + nsCOMPtr doc = do_QueryInterface(domdoc); + NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); + + nsCOMPtr container = doc->GetContainer(); + nsCOMPtr docShell = do_QueryInterface(container); + NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); + + nsCOMPtr hookList = do_GetInterface(docShell); + NS_ENSURE_TRUE(hookList, NS_ERROR_FAILURE); + nsCOMPtr enumerator; + hookList->GetHookEnumerator(getter_AddRefs(enumerator)); + NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE); + + *outEnumerator = enumerator; + NS_ADDREF(*outEnumerator); + + return NS_OK; +} + // // DragGesture // +// Determine if the user has started to drag something and kick off +// an OS-level drag if it's applicable +// NS_IMETHODIMP nsContentAreaDragDrop::DragGesture(nsIDOMEvent* inMouseEvent) { + // first check that someone hasn't already handled this event + PRBool preventDefault = PR_TRUE; + nsCOMPtr nsuiEvent(do_QueryInterface(inMouseEvent)); + if (nsuiEvent) { + nsuiEvent->GetPreventDefault(&preventDefault); + } + + if (preventDefault) { + return NS_OK; + } + + // if the client has provided an override callback, check if we + // should continue + nsCOMPtr enumerator; + GetHookEnumeratorFromEvent(inMouseEvent, getter_AddRefs(enumerator)); + + if (enumerator) { + PRBool allow = PR_TRUE; + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) + && hasMoreHooks) { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + + nsCOMPtr override = do_QueryInterface(isupp); + if (override) { +#ifdef DEBUG + nsresult hookResult = +#endif + override->AllowStartDrag(inMouseEvent, &allow); + NS_ASSERTION(NS_SUCCEEDED(hookResult), + "hook failure in AllowStartDrag"); + + if (!allow) + return NS_OK; + } + } + } + + PRBool isSelection = PR_FALSE; + nsCOMPtr trans; + nsTransferableFactory factory(inMouseEvent, static_cast(this)); + factory.Produce(&isSelection, getter_AddRefs(trans)); + + if (trans) { + // if the client has provided an override callback, let them manipulate + // the flavors or drag data + nsCOMPtr enumerator; + GetHookEnumeratorFromEvent(inMouseEvent, getter_AddRefs(enumerator)); + if (enumerator) { + PRBool hasMoreHooks = PR_FALSE; + PRBool doContinueDrag = PR_TRUE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) + && hasMoreHooks) { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + nsCOMPtr override = + do_QueryInterface(isupp); + + if (override) { +#ifdef DEBUG + nsresult hookResult = +#endif + override->OnCopyOrDrag(inMouseEvent, trans, &doContinueDrag); + NS_ASSERTION(NS_SUCCEEDED(hookResult), + "hook failure in OnCopyOrDrag"); + + if (!doContinueDrag) { + return NS_OK; + } + } + } + } + + nsCOMPtr transArray = + do_CreateInstance("@mozilla.org/supports-array;1"); + if (!transArray) { + return NS_ERROR_FAILURE; + } + + transArray->InsertElementAt(trans, 0); + + // kick off the drag + nsCOMPtr target; + inMouseEvent->GetTarget(getter_AddRefs(target)); + nsCOMPtr dragService = + do_GetService("@mozilla.org/widget/dragservice;1"); + + if (!dragService) { + return NS_ERROR_FAILURE; + } + + PRUint32 action = nsIDragService::DRAGDROP_ACTION_COPY + + nsIDragService::DRAGDROP_ACTION_MOVE + + nsIDragService::DRAGDROP_ACTION_LINK; + + nsCOMPtr mouseEvent(do_QueryInterface(inMouseEvent)); + + if (isSelection) { + nsCOMPtr targetContent(do_QueryInterface(target)); + nsIDocument* doc = targetContent->GetCurrentDoc(); + if (doc) { + nsIPresShell* presShell = doc->GetPrimaryShell(); + if (presShell) { + nsISelection* selection = + presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL); + return dragService->InvokeDragSessionWithSelection(selection, + transArray, + action, + mouseEvent); + } + } + } + + nsCOMPtr targetNode(do_QueryInterface(target)); + dragService->InvokeDragSessionWithImage(targetNode, transArray, nsnull, + action, nsnull, 0, 0, mouseEvent); + } + return NS_OK; } -nsresult -nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow, - nsIContent* aTarget, - nsIContent* aSelectionTargetNode, - PRBool aIsAltKeyPressed, - nsDOMDataTransfer* aDataTransfer, - PRBool* aCanDrag, - PRBool* aDragSelection, - nsIContent** aDragNode) -{ - NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG); - - *aCanDrag = PR_TRUE; - - nsTransferableFactory - factory(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed); - return factory.Produce(aDataTransfer, aCanDrag, aDragSelection, aDragNode); -} - NS_IMETHODIMP nsContentAreaDragDrop::HandleEvent(nsIDOMEvent *event) @@ -639,14 +837,12 @@ nsContentAreaDragDrop::HandleEvent(nsIDOMEvent *event) #pragma mark - #endif -NS_IMPL_ISUPPORTS1(nsContentAreaDragDropDataProvider, nsIFlavorDataProvider) - // SaveURIToFile // used on platforms where it's possible to drag items (e.g. images) // into the file system nsresult -nsContentAreaDragDropDataProvider::SaveURIToFile(nsAString& inSourceURIString, - nsIFile* inDestFile) +nsContentAreaDragDrop::SaveURIToFile(nsAString& inSourceURIString, + nsIFile* inDestFile) { nsCOMPtr sourceURI; nsresult rv = NS_NewURI(getter_AddRefs(sourceURI), inSourceURIString); @@ -669,7 +865,8 @@ nsContentAreaDragDropDataProvider::SaveURIToFile(nsAString& inSourceURIString, &rv); NS_ENSURE_SUCCESS(rv, rv); - return persist->SaveURI(sourceURI, nsnull, nsnull, nsnull, nsnull, inDestFile); + return persist->SaveURI(sourceURI, nsnull, nsnull, nsnull, nsnull, + inDestFile); } // This is our nsIFlavorDataProvider callback. There are several @@ -677,19 +874,18 @@ nsContentAreaDragDropDataProvider::SaveURIToFile(nsAString& inSourceURIString, // // 1. Someone put a kFilePromiseURLMime flavor into the transferable // with the source URI of the file to save (as a string). We did -// that in AddStringsToDataTransfer. +// that above. // // 2. Someone put a kFilePromiseDirectoryMime flavor into the // transferable with an nsILocalFile for the directory we are to // save in. That has to be done by platform-specific code (in -// widget), which gets the destination directory from -// OS-specific drag information. +// widget), // which gets the destination directory from +// OS-specific drag // information. // NS_IMETHODIMP -nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable *aTransferable, - const char *aFlavor, - nsISupports **aData, - PRUint32 *aDataLen) +nsContentAreaDragDrop::GetFlavorData(nsITransferable *aTransferable, + const char *aFlavor, nsISupports **aData, + PRUint32 *aDataLen) { NS_ENSURE_ARG_POINTER(aData && aDataLen); *aData = nsnull; @@ -741,7 +937,9 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable *aTransferable, file->Append(targetFilename); + // now save the file rv = SaveURIToFile(sourceURLString, file); + // send back an nsILocalFile if (NS_SUCCEEDED(rv)) { CallQueryInterface(file, aData); @@ -752,14 +950,11 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable *aTransferable, return rv; } -nsTransferableFactory::nsTransferableFactory(nsIDOMWindow* aWindow, - nsIContent* aTarget, - nsIContent* aSelectionTargetNode, - PRBool aIsAltKeyPressed) - : mWindow(aWindow), - mTarget(aTarget), - mSelectionTargetNode(aSelectionTargetNode), - mIsAltKeyPressed(aIsAltKeyPressed) +nsTransferableFactory::nsTransferableFactory(nsIDOMEvent* inMouseEvent, + nsIFlavorDataProvider *dataProvider) + : mInstanceAlreadyUsed(PR_FALSE), + mMouseEvent(inMouseEvent), + mFlavorDataProvider(dataProvider) { } @@ -771,10 +966,10 @@ nsTransferableFactory::nsTransferableFactory(nsIDOMWindow* aWindow, // it gets up to the root without finding it, we stop looking and // return null. // -already_AddRefed -nsTransferableFactory::FindParentLinkNode(nsIContent* inNode) +already_AddRefed +nsTransferableFactory::FindParentLinkNode(nsIDOMNode* inNode) { - nsIContent* content = inNode; + nsCOMPtr content(do_QueryInterface(inNode)); if (!content) { // That must have been the document node; nothing else to do here; return nsnull; @@ -782,8 +977,9 @@ nsTransferableFactory::FindParentLinkNode(nsIContent* inNode) for (; content; content = content->GetParent()) { if (nsContentUtils::IsDraggableLink(content)) { - NS_ADDREF(content); - return content; + nsIDOMNode* node = nsnull; + CallQueryInterface(content, &node); + return node; } } @@ -795,10 +991,11 @@ nsTransferableFactory::FindParentLinkNode(nsIContent* inNode) // GetAnchorURL // void -nsTransferableFactory::GetAnchorURL(nsIContent* inNode, nsAString& outURL) +nsTransferableFactory::GetAnchorURL(nsIDOMNode* inNode, nsAString& outURL) { nsCOMPtr linkURI; - if (!inNode || !inNode->IsLink(getter_AddRefs(linkURI))) { + nsCOMPtr content = do_QueryInterface(inNode); + if (!content || !content->IsLink(getter_AddRefs(linkURI))) { // Not a link outURL.Truncate(); return; @@ -840,22 +1037,20 @@ nsTransferableFactory::CreateLinkText(const nsAString& inURL, // Gets the text associated with a node // void -nsTransferableFactory::GetNodeString(nsIContent* inNode, +nsTransferableFactory::GetNodeString(nsIDOMNode* inNode, nsAString & outNodeString) { - nsCOMPtr node = do_QueryInterface(inNode); - outNodeString.Truncate(); // use a range to get the text-equivalent of the node nsCOMPtr doc; - node->GetOwnerDocument(getter_AddRefs(doc)); + inNode->GetOwnerDocument(getter_AddRefs(doc)); nsCOMPtr docRange(do_QueryInterface(doc)); if (docRange) { nsCOMPtr range; docRange->CreateRange(getter_AddRefs(range)); if (range) { - range->SelectNode(node); + range->SelectNode(inNode); range->ToString(outNodeString); } } @@ -863,111 +1058,139 @@ nsTransferableFactory::GetNodeString(nsIContent* inNode, nsresult -nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer, - PRBool* aCanDrag, - PRBool* aDragSelection, - nsIContent** aDragNode) +nsTransferableFactory::Produce(PRBool* aDragSelection, + nsITransferable** outTrans) { - NS_PRECONDITION(aCanDrag && aDragSelection && aDataTransfer && aDragNode, - "null pointer passed to Produce"); - NS_ASSERTION(mWindow, "window not set"); - NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set"); + if (mInstanceAlreadyUsed) { + return NS_ERROR_FAILURE; + } - *aDragNode = nsnull; + if (!outTrans || !mMouseEvent || !mFlavorDataProvider) { + return NS_ERROR_FAILURE; + } - nsIContent* dragNode = nsnull; + mInstanceAlreadyUsed = PR_TRUE; + *outTrans = nsnull; + nsCOMPtr window; + PRBool isAltKeyDown = PR_FALSE; mIsAnchor = PR_FALSE; - // find the selection to see what we could be dragging and if - // what we're dragging is in what is selected. + { + nsCOMPtr uiEvent(do_QueryInterface(mMouseEvent)); + if (!uiEvent) { + return NS_OK; + } + + // find the selection to see what we could be dragging and if + // what we're dragging is in what is selected. + nsCOMPtr view; + uiEvent->GetView(getter_AddRefs(view)); + window = do_QueryInterface(view); + if (!window) { + return NS_OK; + } + } + + { + nsCOMPtr mouseEvent(do_QueryInterface(mMouseEvent)); + if (mouseEvent) { + mouseEvent->GetAltKey(&isAltKeyDown); + } + } + nsCOMPtr selection; - mWindow->GetSelection(getter_AddRefs(selection)); + window->GetSelection(getter_AddRefs(selection)); if (!selection) { return NS_OK; } - // check if the node is inside a form control. If so, dragging will be - // handled in editor code (nsPlaintextDataTransfer::DoDrag). Don't set - // aCanDrag to false however, as we still want to allow the drag. - nsCOMPtr findFormNode = mSelectionTargetNode; - nsIContent* findFormParent = findFormNode->GetParent(); - while (findFormParent) { - nsCOMPtr form(do_QueryInterface(findFormParent)); - if (form && form->GetType() != NS_FORM_OBJECT) - return NS_OK; - findFormParent = findFormParent->GetParent(); - } - // if set, serialize the content under this node - nsCOMPtr nodeToSerialize; + nsCOMPtr nodeToSerialize; + PRBool useSelectedText = PR_FALSE; *aDragSelection = PR_FALSE; { PRBool haveSelectedContent = PR_FALSE; // possible parent link node - nsCOMPtr parentLink; - nsCOMPtr draggedNode; + nsCOMPtr parentLink; + nsCOMPtr draggedNode; { + nsCOMPtr target; + mMouseEvent->GetTarget(getter_AddRefs(target)); + // only drag form elements by using the alt key, // otherwise buttons and select widgets are hard to use // Note that while elements implement nsIFormControl, we should // really allow dragging them if they happen to be images. - nsCOMPtr form(do_QueryInterface(mTarget)); - if (form && !mIsAltKeyPressed && form->GetType() != NS_FORM_OBJECT) { - *aCanDrag = PR_FALSE; + nsCOMPtr form(do_QueryInterface(target)); + if (form && !isAltKeyDown && form->GetType() != NS_FORM_OBJECT) { return NS_OK; } - draggedNode = mTarget; + draggedNode = do_QueryInterface(target); } nsCOMPtr area; // client-side image map nsCOMPtr image; nsCOMPtr link; - nsCOMPtr selectedImageOrLinkNode; - GetDraggableSelectionData(selection, mSelectionTargetNode, - getter_AddRefs(selectedImageOrLinkNode), - &haveSelectedContent); + { + // Get the real target and see if it is in the selection + nsCOMPtr realTargetNode; - // either plain text or anchor text is selected - if (haveSelectedContent) { - link = do_QueryInterface(selectedImageOrLinkNode); - if (link && mIsAltKeyPressed) { - // if alt is pressed, select the link text instead of drag the link - *aCanDrag = PR_FALSE; - return NS_OK; + { + nsCOMPtr internalEvent = do_QueryInterface(mMouseEvent); + if (internalEvent) { + nsCOMPtr realTarget; + internalEvent->GetExplicitOriginalTarget(getter_AddRefs(realTarget)); + realTargetNode = do_QueryInterface(realTarget); + } } - *aDragSelection = PR_TRUE; - } else if (selectedImageOrLinkNode) { - // an image is selected - image = do_QueryInterface(selectedImageOrLinkNode); - } else { - // nothing is selected - - // - // look for draggable elements under the mouse - // - // if the alt key is down, don't start a drag if we're in an - // anchor because we want to do selection. - parentLink = FindParentLinkNode(draggedNode); - if (parentLink && mIsAltKeyPressed) { - *aCanDrag = PR_FALSE; - return NS_OK; - } + { + nsCOMPtr selectedImageOrLinkNode; + GetDraggableSelectionData(selection, realTargetNode, + getter_AddRefs(selectedImageOrLinkNode), + &haveSelectedContent); - area = do_QueryInterface(draggedNode); - image = do_QueryInterface(draggedNode); - link = do_QueryInterface(draggedNode); + // either plain text or anchor text is selected + if (haveSelectedContent) { + link = do_QueryInterface(selectedImageOrLinkNode); + if (link && isAltKeyDown) { + return NS_OK; + } + + useSelectedText = PR_TRUE; + *aDragSelection = PR_TRUE; + } else if (selectedImageOrLinkNode) { + // an image is selected + image = do_QueryInterface(selectedImageOrLinkNode); + } else { + // nothing is selected - + // + // look for draggable elements under the mouse + // + // if the alt key is down, don't start a drag if we're in an + // anchor because we want to do selection. + parentLink = FindParentLinkNode(draggedNode); + if (parentLink && isAltKeyDown) { + return NS_OK; + } + + area = do_QueryInterface(draggedNode); + image = do_QueryInterface(draggedNode); + link = do_QueryInterface(draggedNode); + } + } } { // set for linked images, and links - nsCOMPtr linkNode; + nsCOMPtr linkNode; if (area) { // use the alt text (or, if missing, the href) as the title @@ -981,15 +1204,13 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer, mIsAnchor = PR_TRUE; // gives an absolute link - GetAnchorURL(draggedNode, mUrlString); + GetAnchorURL(area, mUrlString); mHtmlString.AssignLiteral(""); mHtmlString.Append(mTitleString); mHtmlString.AppendLiteral(""); - - dragNode = draggedNode; } else if (image) { mIsAnchor = PR_TRUE; // grab the href as the url, use alt text as the title of the @@ -1089,12 +1310,11 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer, linkNode = parentLink; nodeToSerialize = linkNode; } else { - nodeToSerialize = do_QueryInterface(draggedNode); + nodeToSerialize = draggedNode; } - dragNode = nodeToSerialize; } else if (link) { // set linkNode. The code below will handle this - linkNode = do_QueryInterface(link); // XXX test this + linkNode = link; // XXX test this GetNodeString(draggedNode, mTitleString); } else if (parentLink) { // parentLink will always be null if there's selected content @@ -1108,18 +1328,17 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer, if (linkNode) { mIsAnchor = PR_TRUE; GetAnchorURL(linkNode, mUrlString); - dragNode = linkNode; } } } - if (nodeToSerialize || *aDragSelection) { + if (nodeToSerialize || useSelectedText) { // if we have selected text, use it in preference to the node - if (*aDragSelection) { + if (useSelectedText) { nodeToSerialize = nsnull; } - SerializeNodeOrSelection(mWindow, nodeToSerialize, + SerializeNodeOrSelection(window, nodeToSerialize, mHtmlString, mContextString, mInfoString); nsCOMPtr htmlConverter = @@ -1155,37 +1374,16 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer, if (mHtmlString.IsEmpty() && !mUrlString.IsEmpty()) CreateLinkText(mUrlString, mTitleString, mHtmlString); - // if there is no drag node, which will be the case for a selection, just - // use the selection target node. - nsresult rv = AddStringsToDataTransfer( - dragNode ? dragNode : mSelectionTargetNode.get(), aDataTransfer); - NS_ENSURE_SUCCESS(rv, rv); - - NS_IF_ADDREF(*aDragNode = dragNode); - return NS_OK; -} - -void -nsTransferableFactory::AddString(nsDOMDataTransfer* aDataTransfer, - const nsAString& aFlavor, - const nsAString& aData, - nsIPrincipal* aPrincipal) -{ - nsCOMPtr variant = do_CreateInstance(NS_VARIANT_CONTRACTID); - if (variant) { - variant->SetAsAString(aData); - aDataTransfer->SetDataWithPrincipal(aFlavor, variant, 0, aPrincipal); - } + return ConvertStringsToTransferable(outTrans); } nsresult -nsTransferableFactory::AddStringsToDataTransfer(nsIContent* aDragNode, - nsDOMDataTransfer* aDataTransfer) +nsTransferableFactory::ConvertStringsToTransferable(nsITransferable** outTrans) { - NS_ASSERTION(aDragNode, "adding strings for null node"); - - // set all of the data to have the principal of the node where the data came from - nsIPrincipal* principal = aDragNode->NodePrincipal(); + // now create the transferable and stuff data into it. + nsCOMPtr trans = + do_CreateInstance("@mozilla.org/widget/transferable;1"); + NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE); // add a special flavor if we're an anchor to indicate that we have // a URL in the drag data @@ -1194,67 +1392,121 @@ nsTransferableFactory::AddStringsToDataTransfer(nsIContent* aDragNode, dragData.AppendLiteral("\n"); dragData += mTitleString; - AddString(aDataTransfer, NS_LITERAL_STRING(kURLMime), dragData, principal); - AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal); - AddString(aDataTransfer, NS_LITERAL_STRING(kURLDescriptionMime), mTitleString, principal); - AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal); + nsCOMPtr urlPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(urlPrimitive, NS_ERROR_FAILURE); + + urlPrimitive->SetData(dragData); + trans->SetTransferData(kURLMime, urlPrimitive, + dragData.Length() * sizeof(PRUnichar)); + + nsCOMPtr urlDataPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(urlDataPrimitive, NS_ERROR_FAILURE); + + urlDataPrimitive->SetData(mUrlString); + trans->SetTransferData(kURLDataMime, urlDataPrimitive, + mUrlString.Length() * sizeof(PRUnichar)); + + nsCOMPtr urlDescPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(urlDescPrimitive, NS_ERROR_FAILURE); + + urlDescPrimitive->SetData(mTitleString); + trans->SetTransferData(kURLDescriptionMime, urlDescPrimitive, + mTitleString.Length() * sizeof(PRUnichar)); } // add a special flavor, even if we don't have html context data - AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal); + nsCOMPtr context = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(context, NS_ERROR_FAILURE); + + nsAutoString contextData(mContextString); + context->SetData(contextData); + trans->SetTransferData(kHTMLContext, context, contextData.Length() * 2); // add a special flavor if we have html info data - if (!mInfoString.IsEmpty()) - AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal); + if (!mInfoString.IsEmpty()) { + nsCOMPtr info = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(info, NS_ERROR_FAILURE); + + nsAutoString infoData(mInfoString); + info->SetData(infoData); + trans->SetTransferData(kHTMLInfo, info, infoData.Length() * 2); + } // add the full html - AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal); + nsCOMPtr htmlPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(htmlPrimitive, NS_ERROR_FAILURE); - // add the plain text. we use the url for text/plain data if an anchor is - // being dragged, rather than the title text of the link or the alt text for - // an anchor image. - AddString(aDataTransfer, NS_LITERAL_STRING(kTextMime), - mIsAnchor ? mUrlString : mTitleString, principal); + htmlPrimitive->SetData(mHtmlString); + trans->SetTransferData(kHTMLMime, htmlPrimitive, + mHtmlString.Length() * sizeof(PRUnichar)); + + // add the plain (unicode) text. we use the url for text/unicode + // data if an anchor is being dragged, rather than the title text of + // the link or the alt text for an anchor image. + nsCOMPtr textPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(textPrimitive, NS_ERROR_FAILURE); + + textPrimitive->SetData(mIsAnchor ? mUrlString : mTitleString); + trans->SetTransferData(kUnicodeMime, textPrimitive, + (mIsAnchor ? mUrlString.Length() : + mTitleString.Length()) * sizeof(PRUnichar)); // add image data, if present. For now, all we're going to do with // this is turn it into a native data flavor, so indicate that with // a new flavor so as not to confuse anyone who is really registered // for image/gif or image/jpg. if (mImage) { - nsCOMPtr variant = do_CreateInstance(NS_VARIANT_CONTRACTID); - if (variant) { - variant->SetAsISupports(mImage); - aDataTransfer->SetDataWithPrincipal(NS_LITERAL_STRING(kNativeImageMime), - variant, 0, principal); - } + nsCOMPtr ptrPrimitive = + do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID); + NS_ENSURE_TRUE(ptrPrimitive, NS_ERROR_FAILURE); + ptrPrimitive->SetData(mImage); + trans->SetTransferData(kNativeImageMime, ptrPrimitive, + sizeof(nsISupportsInterfacePointer*)); // assume the image comes from a file, and add a file promise. We // register ourselves as a nsIFlavorDataProvider, and will use the // GetFlavorData callback to save the image to disk. + trans->SetTransferData(kFilePromiseMime, mFlavorDataProvider, + nsITransferable::kFlavorHasDataProvider); - nsCOMPtr dataProvider = - new nsContentAreaDragDropDataProvider(); - if (dataProvider) { - nsCOMPtr variant = do_CreateInstance(NS_VARIANT_CONTRACTID); - if (variant) { - variant->SetAsISupports(dataProvider); - aDataTransfer->SetDataWithPrincipal(NS_LITERAL_STRING(kFilePromiseMime), - variant, 0, principal); - } - } + nsCOMPtr imageUrlPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(imageUrlPrimitive, NS_ERROR_FAILURE); - AddString(aDataTransfer, NS_LITERAL_STRING(kFilePromiseURLMime), - mImageSourceString, principal); - AddString(aDataTransfer, NS_LITERAL_STRING(kFilePromiseDestFilename), - mImageDestFileName, principal); + imageUrlPrimitive->SetData(mImageSourceString); + trans->SetTransferData(kFilePromiseURLMime, imageUrlPrimitive, + mImageSourceString.Length() * sizeof(PRUnichar)); + + nsCOMPtr imageFileNamePrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(imageFileNamePrimitive, NS_ERROR_FAILURE); + + imageFileNamePrimitive->SetData(mImageDestFileName); + trans->SetTransferData(kFilePromiseDestFilename, imageFileNamePrimitive, + mImageDestFileName.Length() * sizeof(PRUnichar)); // if not an anchor, add the image url if (!mIsAnchor) { - AddString(aDataTransfer, NS_LITERAL_STRING(kURLDataMime), mUrlString, principal); - AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal); + nsCOMPtr urlDataPrimitive = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + NS_ENSURE_TRUE(urlDataPrimitive, NS_ERROR_FAILURE); + + urlDataPrimitive->SetData(mUrlString); + trans->SetTransferData(kURLDataMime, urlDataPrimitive, + mUrlString.Length() * sizeof(PRUnichar)); } } + *outTrans = trans; + NS_IF_ADDREF(*outTrans); + return NS_OK; } @@ -1262,8 +1514,8 @@ nsTransferableFactory::AddStringsToDataTransfer(nsIContent* aDragNode, // static nsresult nsTransferableFactory::GetDraggableSelectionData(nsISelection* inSelection, - nsIContent* inRealTargetNode, - nsIContent **outImageOrLinkNode, + nsIDOMNode* inRealTargetNode, + nsIDOMNode **outImageOrLinkNode, PRBool* outDragSelectedText) { NS_ENSURE_ARG(inSelection); @@ -1278,8 +1530,7 @@ nsTransferableFactory::GetDraggableSelectionData(nsISelection* inSelection, PRBool isCollapsed = PR_FALSE; inSelection->GetIsCollapsed(&isCollapsed); if (!isCollapsed) { - nsCOMPtr realTargetNode = do_QueryInterface(inRealTargetNode); - inSelection->ContainsNode(realTargetNode, PR_FALSE, + inSelection->ContainsNode(inRealTargetNode, PR_FALSE, &selectionContainsTarget); if (selectionContainsTarget) { @@ -1313,7 +1564,8 @@ nsTransferableFactory::GetDraggableSelectionData(nsISelection* inSelection, // if we find an image, we'll fall into the node-dragging code, // rather the the selection-dragging code if (nsContentUtils::IsDraggableImage(childContent)) { - NS_ADDREF(*outImageOrLinkNode = childContent); + CallQueryInterface(childContent, outImageOrLinkNode); + return NS_OK; } } @@ -1334,21 +1586,20 @@ nsTransferableFactory::GetDraggableSelectionData(nsISelection* inSelection, // static void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, - nsIContent **outLinkNode) + nsIDOMNode **outLinkNode) { *outLinkNode = nsnull; - nsCOMPtr selectionStartNode; - inSelection->GetAnchorNode(getter_AddRefs(selectionStartNode)); - nsCOMPtr selectionEndNode; - inSelection->GetFocusNode(getter_AddRefs(selectionEndNode)); + nsCOMPtr selectionStart; + inSelection->GetAnchorNode(getter_AddRefs(selectionStart)); + nsCOMPtr selectionEnd; + inSelection->GetFocusNode(getter_AddRefs(selectionEnd)); // simple case: only one node is selected // see if it or its parent is an anchor, then exit - if (selectionStartNode == selectionEndNode) { - nsCOMPtr selectionStart = do_QueryInterface(selectionStartNode); - nsCOMPtr link = FindParentLinkNode(selectionStart); + if (selectionStart == selectionEnd) { + nsCOMPtr link = FindParentLinkNode(selectionStart); if (link) { link.swap(*outLinkNode); } @@ -1376,9 +1627,9 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, nsCOMPtr tempNode; range->GetStartContainer( getter_AddRefs(tempNode)); - if (tempNode != selectionStartNode) { - selectionEndNode = selectionStartNode; - selectionStartNode = tempNode; + if (tempNode != selectionStart) { + selectionEnd = selectionStart; + selectionStart = tempNode; inSelection->GetAnchorOffset(&endOffset); inSelection->GetFocusOffset(&startOffset); } else { @@ -1391,17 +1642,17 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, // the selection starts at the end of the text nsAutoString nodeStr; - selectionStartNode->GetNodeValue(nodeStr); + selectionStart->GetNodeValue(nodeStr); if (nodeStr.IsEmpty() || startOffset+1 >= static_cast(nodeStr.Length())) { - nsCOMPtr curr = selectionStartNode; + nsCOMPtr curr = selectionStart; nsIDOMNode* next; while (curr) { curr->GetNextSibling(&next); if (next) { - selectionStartNode = dont_AddRef(next); + selectionStart = dont_AddRef(next); break; } @@ -1413,14 +1664,14 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, // trim trailing node if the selection ends before its text begins if (endOffset == 0) { - nsCOMPtr curr = selectionEndNode; + nsCOMPtr curr = selectionEnd; nsIDOMNode* next; while (curr) { curr->GetPreviousSibling(&next); if (next){ - selectionEndNode = dont_AddRef(next); + selectionEnd = dont_AddRef(next); break; } @@ -1431,11 +1682,9 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, // see if the leading & trailing nodes are part of the // same anchor - if so, return the anchor node - nsCOMPtr selectionStart = do_QueryInterface(selectionStartNode); - nsCOMPtr link = FindParentLinkNode(selectionStart); + nsCOMPtr link = FindParentLinkNode(selectionStart); if (link) { - nsCOMPtr selectionEnd = do_QueryInterface(selectionEndNode); - nsCOMPtr link2 = FindParentLinkNode(selectionEnd); + nsCOMPtr link2 = FindParentLinkNode(selectionEnd); if (link == link2) { NS_IF_ADDREF(*outLinkNode = link); @@ -1448,7 +1697,7 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection, // static nsresult nsTransferableFactory::SerializeNodeOrSelection(nsIDOMWindow* inWindow, - nsIContent* inNode, + nsIDOMNode* inNode, nsAString& outResultString, nsAString& outContext, nsAString& outInfo) @@ -1468,12 +1717,11 @@ nsTransferableFactory::SerializeNodeOrSelection(nsIDOMWindow* inWindow, nsIDocumentEncoder::OutputEncodeHTMLEntities; nsCOMPtr range; nsCOMPtr selection; - nsCOMPtr node = do_QueryInterface(inNode); - if (node) { + if (inNode) { // make a range around this node rv = NS_NewRange(getter_AddRefs(range)); NS_ENSURE_SUCCESS(rv, rv); - rv = range->SelectNode(node); + rv = range->SelectNode(inNode); NS_ENSURE_SUCCESS(rv, rv); } else { inWindow->GetSelection(getter_AddRefs(selection)); diff --git a/content/base/src/nsContentAreaDragDrop.h b/content/base/src/nsContentAreaDragDrop.h index 05379d26a20..16549bc6452 100644 --- a/content/base/src/nsContentAreaDragDrop.h +++ b/content/base/src/nsContentAreaDragDrop.h @@ -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__ */ diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 9a5214a9f1f..d03640f72ff 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -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 -nsContentUtils::GetDragSession() -{ - nsIDragSession* dragSession = nsnull; - nsCOMPtr dragService = - do_GetService("@mozilla.org/widget/dragservice;1"); - if (dragService) - dragService->GetCurrentSession(&dragSession); - return dragSession; -} - /* static */ PRBool nsContentUtils::URIIsLocalFile(nsIURI *aURI) diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 2cbca188510..12957d177de 100755 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -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") diff --git a/content/events/public/nsIPrivateDOMEvent.h b/content/events/public/nsIPrivateDOMEvent.h index b6eec38d49b..8f79b1cce7d 100644 --- a/content/events/public/nsIPrivateDOMEvent.h +++ b/content/events/public/nsIPrivateDOMEvent.h @@ -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); diff --git a/content/events/src/Makefile.in b/content/events/src/Makefile.in index 9da0cc3b9ab..54d1b6626ae 100644 --- a/content/events/src/Makefile.in +++ b/content/events/src/Makefile.in @@ -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. diff --git a/content/events/src/nsDOMDataTransfer.cpp b/content/events/src/nsDOMDataTransfer.cpp deleted file mode 100644 index 499d61eec43..00000000000 --- a/content/events/src/nsDOMDataTransfer.cpp +++ /dev/null @@ -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 - * - * 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 >& 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 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 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 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& 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& 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& 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 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& item = mItems[i]; - PRUint32 count = item.Length(); - if (!count) - continue; - - nsCOMPtr 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 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 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 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 - 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& 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* 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 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 dragService = - do_GetService("@mozilla.org/widget/dragservice;1"); - if (!dragService) - return; - - nsCOMPtr 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 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 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 dragService = - do_GetService("@mozilla.org/widget/dragservice;1"); - if (!dragService) - return; - - nsCOMPtr dragSession; - dragService->GetCurrentSession(getter_AddRefs(dragSession)); - if (!dragSession) - return; - - trans->AddDataFlavor(format); - dragSession->GetData(trans, aIndex); - - PRUint32 length = 0; - nsCOMPtr data; - trans->GetTransferData(format, getter_AddRefs(data), &length); - if (!data) - return; - - nsCOMPtr variant = do_CreateInstance(NS_VARIANT_CONTRACTID); - if (!variant) - return; - - nsCOMPtr supportsstr = do_QueryInterface(data); - if (supportsstr) { - nsAutoString str; - supportsstr->GetData(str); - variant->SetAsAString(str); - } - else { - variant->SetAsISupports(data); - } - aItem.mData = variant; - } -} diff --git a/content/events/src/nsDOMDataTransfer.h b/content/events/src/nsDOMDataTransfer.h deleted file mode 100644 index d09159f6684..00000000000 --- a/content/events/src/nsDOMDataTransfer.h +++ /dev/null @@ -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 - * - * 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 mPrincipal; - nsCOMPtr 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 >& 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 > mItems; - - // the target of the drag. The drag and dragend events will fire at this. - nsCOMPtr mDragTarget; - - // the custom drag image and coordinates within the image. If mDragImage is - // null, the default image is created from the drag target. - nsCOMPtr mDragImage; - PRUint32 mDragImageX; - PRUint32 mDragImageY; -}; - -#endif // nsDOMDataTransfer_h__ - diff --git a/content/events/src/nsDOMDragEvent.cpp b/content/events/src/nsDOMDragEvent.cpp deleted file mode 100644 index a14bd3697b6..00000000000 --- a/content/events/src/nsDOMDragEvent.cpp +++ /dev/null @@ -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 - * - * 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(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(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(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 dragSession = nsContentUtils::GetDragSession(); - NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress - - nsCOMPtr 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 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 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 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); -} diff --git a/content/events/src/nsDOMDragEvent.h b/content/events/src/nsDOMDragEvent.h deleted file mode 100644 index 5bfba1c90e4..00000000000 --- a/content/events/src/nsDOMDragEvent.h +++ /dev/null @@ -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 - * - * 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__ diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index 9961b4c0df1..90d42ac6fcc 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -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(tmp->mEvent)->relatedTarget = nsnull; break; - case NS_DRAG_EVENT: - static_cast(tmp->mEvent)->dataTransfer = nsnull; - break; case NS_XUL_COMMAND_EVENT: static_cast(tmp->mEvent)->sourceEvent = nsnull; break; @@ -201,10 +198,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent) cb.NoteXPCOMChild( static_cast(tmp->mEvent)->relatedTarget); break; - case NS_DRAG_EVENT: - cb.NoteXPCOMChild( - static_cast(tmp->mEvent)->dataTransfer); - break; case NS_XUL_COMMAND_EVENT: cb.NoteXPCOMChild( static_cast(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(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: diff --git a/content/events/src/nsDOMEvent.h b/content/events/src/nsDOMEvent.h index 8178eac74c0..7996956f000 100644 --- a/content/events/src/nsDOMEvent.h +++ b/content/events/src/nsDOMEvent.h @@ -103,9 +103,6 @@ public: eDOMEvents_draggesture, eDOMEvents_drag, eDOMEvents_dragend, - eDOMEvents_dragstart, - eDOMEvents_dragleave, - eDOMEvents_drop, eDOMEvents_resize, eDOMEvents_scroll, eDOMEvents_overflow, diff --git a/content/events/src/nsDOMMouseEvent.h b/content/events/src/nsDOMMouseEvent.h index 0b6d47201e0..c4808401080 100644 --- a/content/events/src/nsDOMMouseEvent.h +++ b/content/events/src/nsDOMMouseEvent.h @@ -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 diff --git a/content/events/src/nsDOMUIEvent.cpp b/content/events/src/nsDOMUIEvent.cpp index 805ddc5bca9..feb270a96f2 100644 --- a/content/events/src/nsDOMUIEvent.cpp +++ b/content/events/src/nsDOMUIEvent.cpp @@ -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; diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp index 2b6a8575296..f4d6730352b 100644 --- a/content/events/src/nsEventDispatcher.cpp +++ b/content/events/src/nsEventDispatcher.cpp @@ -576,9 +576,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext, case NS_MOUSE_SCROLL_EVENT: return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext, static_cast(aEvent)); - case NS_DRAG_EVENT: - return NS_NewDOMDragEvent(aDOMEvent, aPresContext, - static_cast(aEvent)); case NS_POPUPBLOCKED_EVENT: return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext, static_cast @@ -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); diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 5186abbdb85..c06f4d78c9b 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -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[] = { diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index c135339d46a..9c118a63c31 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -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 #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 dataTransfer = new nsDOMDataTransfer(); - if (!dataTransfer) - return; - - PRBool isSelection = PR_FALSE; - nsCOMPtr eventContent, targetContent; - mCurrentTarget->GetContentForEvent(aPresContext, aEvent, - getter_AddRefs(eventContent)); - if (eventContent) - DetermineDragTarget(aPresContext, eventContent, dataTransfer, - &isSelection, getter_AddRefs(targetContent)); - + nsCOMPtr targetContent = mGestureDownContent; // Stop tracking the drag gesture now. This should stop us from // reentering GenerateDragGesture inside DOM event processing. StopTrackingDragGesture(); - if (!targetContent) - return; - nsCOMPtr 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 container = aPresContext->GetContainer(); - nsCOMPtr 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 dragDataNode; - nsCOMPtr 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 htmlElement = do_QueryInterface(dragContent); - if (htmlElement) { - PRBool draggable = PR_FALSE; - htmlElement->GetDraggable(&draggable); - if (draggable) - break; - } - else { - nsCOMPtr 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 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 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 dragTarget; - nsCOMPtr 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 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 domEvent; - NS_NewDOMDragEvent(getter_AddRefs(domEvent), aPresContext, aDragEvent); - - nsCOMPtr 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 region; -#ifdef MOZ_XUL - if (dragTarget && !dragImage) { - nsCOMPtr 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 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 dataTransfer; - nsCOMPtr initialDataTransfer; - dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer)); - - nsCOMPtr 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 targetContent; - mCurrentTarget->GetContentForEvent(presContext, aEvent, - getter_AddRefs(targetContent)); - - nsCOMPtr widget = mCurrentTarget->GetWindow(); - nsDragEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_DRAGDROP, widget); - - nsMouseEvent* mouseEvent = static_cast(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 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 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; diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index c438cd40da7..d7b2bb06c60 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -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 diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in index 9e8986ad500..01ece8b8f74 100644 --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -61,8 +61,6 @@ _TEST_FILES = \ test_bug412567.html \ test_bug443985.html \ test_bug447736.html \ - test_draggableprop.html \ - test_dragstart.html \ $(NULL) _CHROME_FILES = \ diff --git a/content/events/test/test_draggableprop.html b/content/events/test/test_draggableprop.html deleted file mode 100644 index 03300cc73fb..00000000000 --- a/content/events/test/test_draggableprop.html +++ /dev/null @@ -1,91 +0,0 @@ - - - Tests for the draggable property on HTML elements - - - - - -

- - -One -Two -Three -Four -Five - - - - - - - -One -Two -Three -Four -Five - -One -Two -Three -Four -Five - - - - - - - diff --git a/content/events/test/test_dragstart.html b/content/events/test/test_dragstart.html deleted file mode 100644 index 10bbcca65b2..00000000000 --- a/content/events/test/test_dragstart.html +++ /dev/null @@ -1,526 +0,0 @@ - - - Tests for the dragstart event - - - - - - - - - - - - - -
This is a draggable bit of text.
- -mozilla.org - - - - - -
-
- This is a draggable area. -
-
- This is a non-draggable area. -
-
- - - -
Synthetic Event Dispatch
-
Synthetic Event Dispatch
- - - diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 64956f54e6d..741989c1205 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -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) { diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index 69c75aeca36..ecb120174d0 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -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); diff --git a/content/html/content/src/nsHTMLAnchorElement.cpp b/content/html/content/src/nsHTMLAnchorElement.cpp index 006cbccc183..b376db99575 100644 --- a/content/html/content/src/nsHTMLAnchorElement.cpp +++ b/content/html/content/src/nsHTMLAnchorElement.cpp @@ -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, diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index 95f17fa4fdf..2251a905c08 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -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) { diff --git a/dom/public/coreEvents/nsIDOMDragListener.h b/dom/public/coreEvents/nsIDOMDragListener.h index 66a383c684f..53359cd8c96 100644 --- a/dom/public/coreEvents/nsIDOMDragListener.h +++ b/dom/public/coreEvents/nsIDOMDragListener.h @@ -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) diff --git a/dom/public/idl/events/Makefile.in b/dom/public/idl/events/Makefile.in index c3a034d5abd..e3a397d5651 100644 --- a/dom/public/idl/events/Makefile.in +++ b/dom/public/idl/events/Makefile.in @@ -67,8 +67,6 @@ XPIDLSRCS = \ nsIDOMKeyEvent.idl \ nsIDOMMutationEvent.idl \ nsIDOMNSUIEvent.idl \ - nsIDOMDragEvent.idl \ - nsIDOMDataTransfer.idl \ nsIDOMPopupBlockedEvent.idl \ nsIDOMBeforeUnloadEvent.idl \ nsIDOMNSEventTarget.idl \ diff --git a/dom/public/idl/events/nsIDOMDataTransfer.idl b/dom/public/idl/events/nsIDOMDataTransfer.idl deleted file mode 100644 index c516f28e6a3..00000000000 --- a/dom/public/idl/events/nsIDOMDataTransfer.idl +++ /dev/null @@ -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 - * - * 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); -}; diff --git a/dom/public/idl/events/nsIDOMDragEvent.idl b/dom/public/idl/events/nsIDOMDragEvent.idl deleted file mode 100644 index dc8109f1a53..00000000000 --- a/dom/public/idl/events/nsIDOMDragEvent.idl +++ /dev/null @@ -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 - * - * 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); -}; diff --git a/dom/public/idl/html/nsIDOMNSHTMLElement.idl b/dom/public/idl/html/nsIDOMNSHTMLElement.idl index aaa996a742d..48d096d4cbb 100644 --- a/dom/public/idl/html/nsIDOMNSHTMLElement.idl +++ b/dom/public/idl/html/nsIDOMNSHTMLElement.idl @@ -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(); diff --git a/dom/public/nsDOMClassInfoID.h b/dom/public/nsDOMClassInfoID.h index 047f140ebc3..51e622b04eb 100644 --- a/dom/public/nsDOMClassInfoID.h +++ b/dom/public/nsDOMClassInfoID.h @@ -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 }; diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index c0140db18ce..02ac768cf42 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -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); diff --git a/editor/libeditor/base/nsEditorUtils.cpp b/editor/libeditor/base/nsEditorUtils.cpp index af7182685f8..479fab21fa5 100644 --- a/editor/libeditor/base/nsEditorUtils.cpp +++ b/editor/libeditor/base/nsEditorUtils.cpp @@ -253,6 +253,95 @@ nsEditorHookUtils::GetHookEnumeratorFromDocument(nsIDOMDocument *aDoc, return hookObj->GetHookEnumerator(aResult); } +PRBool +nsEditorHookUtils::DoAllowDragHook(nsIDOMDocument *aDoc, nsIDOMEvent *aDragEvent) +{ + nsCOMPtr enumerator; + GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator)); + if (!enumerator) + return PR_TRUE; + + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks) + { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + + nsCOMPtr 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 enumerator; + GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator)); + if (!enumerator) + return PR_TRUE; + + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks) + { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + + nsCOMPtr 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 enumerator; + GetHookEnumeratorFromDocument(aDoc, getter_AddRefs(enumerator)); + if (!enumerator) + return PR_TRUE; + + PRBool hasMoreHooks = PR_FALSE; + while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreHooks)) && hasMoreHooks) + { + nsCOMPtr isupp; + if (NS_FAILED(enumerator->GetNext(getter_AddRefs(isupp)))) + break; + + nsCOMPtr 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) diff --git a/editor/libeditor/base/nsEditorUtils.h b/editor/libeditor/base/nsEditorUtils.h index 607e35ca5d4..f77d19b15cc 100644 --- a/editor/libeditor/base/nsEditorUtils.h +++ b/editor/libeditor/base/nsEditorUtils.h @@ -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: diff --git a/editor/libeditor/html/nsHTMLDataTransfer.cpp b/editor/libeditor/html/nsHTMLDataTransfer.cpp index 28ba02e1ae7..eebabc5a01e 100644 --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp @@ -1497,6 +1497,8 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromDrop(nsIDOMEvent* aDropEvent) // transferable hooks here nsCOMPtr 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. diff --git a/editor/libeditor/text/nsEditorEventListeners.cpp b/editor/libeditor/text/nsEditorEventListeners.cpp index 455c35962d2..54f78adb44e 100644 --- a/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/editor/libeditor/text/nsEditorEventListeners.cpp @@ -570,6 +570,13 @@ nsTextEditorDragListener::DragOver(nsIDOMEvent* aDragEvent) } PRBool canDrop = CanDrop(aDragEvent); + if (canDrop) + { + nsCOMPtr 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 diff --git a/editor/libeditor/text/nsPlaintextDataTransfer.cpp b/editor/libeditor/text/nsPlaintextDataTransfer.cpp index 1b26b7cf4bc..be84feeab98 100644 --- a/editor/libeditor/text/nsPlaintextDataTransfer.cpp +++ b/editor/libeditor/text/nsPlaintextDataTransfer.cpp @@ -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 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 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 domdoc; GetDocument(getter_AddRefs(domdoc)); + if (!nsEditorHookUtils::DoDragHook(domdoc, aDragEvent, trans)) + return NS_OK; /* invoke drag */ nsCOMPtr 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 dragEvent(do_QueryInterface(aDragEvent)); + nsCOMPtr mouseEvent(do_QueryInterface(aDragEvent)); rv = dragService->InvokeDragSessionWithSelection(selection, transferableArray, - flags, dragEvent, nsnull); + flags, mouseEvent); if (NS_FAILED(rv)) return rv; aDragEvent->StopPropagation(); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 147f7df4703..3458f4ca19e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -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(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(aEvent); diff --git a/layout/xul/base/src/tree/public/nsITreeBoxObject.idl b/layout/xul/base/src/tree/public/nsITreeBoxObject.idl index 07c02dad254..b162263b221 100644 --- a/layout/xul/base/src/tree/public/nsITreeBoxObject.idl +++ b/layout/xul/base/src/tree/public/nsITreeBoxObject.idl @@ -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. */ diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index 179790fcb71..a1f3e136025 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -642,48 +642,6 @@ nsTreeBodyFrame::GetPageLength(PRInt32 *_retval) return NS_OK; } -NS_IMETHODIMP -nsTreeBodyFrame::GetSelectionRegion(nsIScriptableRegion **aRegion) -{ - *aRegion = nsnull; - - nsCOMPtr selection; - mView->GetSelection(getter_AddRefs(selection)); - NS_ENSURE_TRUE(selection, NS_OK); - - nsCOMPtr region = do_CreateInstance("@mozilla.org/gfx/region;1"); - NS_ENSURE_TRUE(region, NS_ERROR_FAILURE); - region->Init(); - - nsRefPtr 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; diff --git a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp index d6335f68461..b9d275ac05a 100644 --- a/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBoxObject.cpp @@ -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) { diff --git a/testing/mochitest/tests/SimpleTest/EventUtils.js b/testing/mochitest/tests/SimpleTest/EventUtils.js index b7a323463cf..52f8f8b8cbc 100644 --- a/testing/mochitest/tests/SimpleTest/EventUtils.js +++ b/testing/mochitest/tests/SimpleTest/EventUtils.js @@ -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); diff --git a/toolkit/content/nsDragAndDrop.js b/toolkit/content/nsDragAndDrop.js index 55ae9d18bc5..5cfc6210527 100644 --- a/toolkit/content/nsDragAndDrop.js +++ b/toolkit/content/nsDragAndDrop.js @@ -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) ; diff --git a/widget/public/nsGUIEvent.h b/widget/public/nsGUIEvent.h index 6550245bd79..5274da9f349 100644 --- a/widget/public/nsGUIEvent.h +++ b/widget/public/nsGUIEvent.h @@ -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 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) || \ diff --git a/widget/public/nsIDragService.idl b/widget/public/nsIDragService.idl index 3ca6b25fe70..1c5c1600d87 100644 --- a/widget/public/nsIDragService.idl +++ b/widget/public/nsIDragService.idl @@ -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 diff --git a/widget/public/nsIDragSession.idl b/widget/public/nsIDragSession.idl index d13ba448049..ba88a73a8b4 100644 --- a/widget/public/nsIDragSession.idl +++ b/widget/public/nsIDragSession.idl @@ -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. diff --git a/widget/src/beos/nsWindow.cpp b/widget/src/beos/nsWindow.cpp index 7a9b896a0d7..19f01d15ba1 100644 --- a/widget/src/beos/nsWindow.cpp +++ b/widget/src/beos/nsWindow.cpp @@ -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]; diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 9346e605850..3a1f6f912fa 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -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 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 sourceNode; dragSession->GetSourceNode(getter_AddRefs(sourceNode)); if (!sourceNode) { diff --git a/widget/src/cocoa/nsDragService.mm b/widget/src/cocoa/nsDragService.mm index f51667bdddc..b8a3de95bbf 100644 --- a/widget/src/cocoa/nsDragService.mm +++ b/widget/src/cocoa/nsDragService.mm @@ -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; } diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index ac3ed49e3d3..6bfe9c92689 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -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) { diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h index d094545a618..686772308ae 100644 --- a/widget/src/gtk2/nsWindow.h +++ b/widget/src/gtk2/nsWindow.h @@ -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); diff --git a/widget/src/os2/nsWindow.cpp b/widget/src/os2/nsWindow.cpp index 03338dea091..b58dfb239af 100644 --- a/widget/src/os2/nsWindow.cpp +++ b/widget/src/os2/nsWindow.cpp @@ -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); diff --git a/widget/src/photon/nsWidget.cpp b/widget/src/photon/nsWidget.cpp index 264740a1575..d455473dc78 100644 --- a/widget/src/photon/nsWidget.cpp +++ b/widget/src/photon/nsWidget.cpp @@ -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 ); diff --git a/widget/src/windows/nsNativeDragTarget.cpp b/widget/src/windows/nsNativeDragTarget.cpp index 335b009a103..2bcf9ed5c53 100644 --- a/widget/src/windows/nsNativeDragTarget.cpp +++ b/widget/src/windows/nsNativeDragTarget.cpp @@ -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(mWindow); win->InitEvent(event); diff --git a/widget/src/xpwidgets/nsBaseDragService.cpp b/widget/src/xpwidgets/nsBaseDragService.cpp index f177b617b47..01f250a42ff 100644 --- a/widget/src/xpwidgets/nsBaseDragService.cpp +++ b/widget/src/xpwidgets/nsBaseDragService.cpp @@ -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 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 presShell = doc->GetPrimaryShell(); if (presShell) { nsEventStatus status = nsEventStatus_eIgnore; - nsDragEvent event(PR_TRUE, aMsg, nsnull); + nsMouseEvent event(PR_TRUE, aMsg, nsnull, nsMouseEvent::eReal); nsCOMPtr content = do_QueryInterface(mSourceNode); return presShell->HandleDOMEventWithTarget(content, &event, &status); diff --git a/widget/src/xpwidgets/nsBaseDragService.h b/widget/src/xpwidgets/nsBaseDragService.h index 900e7541bff..3bcf348dea4 100644 --- a/widget/src/xpwidgets/nsBaseDragService.h +++ b/widget/src/xpwidgets/nsBaseDragService.h @@ -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 mSourceNode; nsCOMPtr mSourceDocument; // the document at the drag source. will be null // if it came from outside the app. - nsCOMPtr mDataTransfer; // used to determine the image to appear on the cursor while dragging nsCOMPtr mImage; diff --git a/widget/src/xpwidgets/nsPrimitiveHelpers.cpp b/widget/src/xpwidgets/nsPrimitiveHelpers.cpp index c206e22823e..3d7fd84c2d2 100644 --- a/widget/src/xpwidgets/nsPrimitiveHelpers.cpp +++ b/widget/src/xpwidgets/nsPrimitiveHelpers.cpp @@ -134,8 +134,6 @@ nsPrimitiveHelpers :: CreateDataFromPrimitive ( const char* aFlavor, nsISupports if ( !aDataBuff ) return; - *aDataBuff = nsnull; - if ( strcmp(aFlavor,kTextMime) == 0 ) { nsCOMPtr plainText ( do_QueryInterface(aPrimitive) ); if ( plainText ) { diff --git a/xpfe/global/jar.mn b/xpfe/global/jar.mn index c3eb8c93f63..c442403b694 100644 --- a/xpfe/global/jar.mn +++ b/xpfe/global/jar.mn @@ -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)