api for overriding aspects of content-area drag&drop. r=ccarlen/sr=sfraser/a=shaver. bug# 126069

git-svn-id: svn://10.0.0.236/trunk@115506 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pinkerton%netscape.com 2002-02-28 22:19:04 +00:00
parent a81db5e449
commit ddc4e56e6d
10 changed files with 235 additions and 18 deletions

View File

@ -13,3 +13,5 @@ nsIPrintProgress.idl
nsIPrintStatusFeedback.idl
nsIPrintProgressParams.idl
nsIDragDropHandler.idl
nsIDragDropOverride.idl

View File

@ -71,6 +71,7 @@ XPIDLSRCS = \
nsIPrintProgressParams.idl \
nsIPrintStatusFeedback.idl \
nsIDragDropHandler.idl \
nsIDragDropOverride.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -66,6 +66,7 @@ XPIDLSRCS= \
.\nsIPrintStatusFeedback.idl \
.\nsIPrintProgressParams.idl \
.\nsIDragDropHandler.idl \
.\nsIDragDropOverride.idl \
$(NULL)

View File

@ -39,6 +39,13 @@
interface nsIDOMEventTarget;
interface nsIWebNavigation;
interface nsIOverrideDragSource;
interface nsIOverrideDropSite;
/**
* @status UNDER_REVIEW
*/
/**
* Interface for communicating with the built-in drag and drop
@ -50,12 +57,26 @@ interface nsIWebNavigation;
[scriptable,uuid(4f418f58-f834-4736-a755-e0395bedca9d)]
interface nsIDragDropHandler : nsISupports
{
// attach drag handlers to the receiver specified in |attachPoint|. If
// |navigator| is supplied (it can be null), then if urls are dropped
// on the content area they will be loaded through the object provided. If
// it is null, then the client must handle the drop itself.
void hookupTo(in nsIDOMEventTarget attachPoint, in nsIWebNavigation navigator);
/**
* Attach drag handlers to receiver specified by |attachPoint| and
* specify callbacks to allow overriding of the built-in behaviors.
*
* @param attachPoint hookup listeners to this location
* @param navigator loads dropped urls via this interface. If NULL,
* the client must handle the drop itself, either
* through the method provided via |overrideDrop| or
* by letting the event bubble up through the DOM.
* @param overrideDrag callback to client to override portions of the
* drag start action. Can be NULL.
* @param overrideDrop callback to client to override portions of the
* drop action. Can be NULL.
*/
void hookupTo(in nsIDOMEventTarget attachPoint, in nsIWebNavigation navigator,
in nsIOverrideDragSource overrideDrag,
in nsIOverrideDropSite overrideDrop);
// call to unregister all handlers related to drag&drop
/**
* Unregister all handlers related to drag&drop
*/
void detach();
};

View File

@ -0,0 +1,122 @@
/* ***** 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 Communicator.
*
* The Initial Developer of the Original Code is
* Netscape Communications.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Pinkerton <pinkerton@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 "nsISupports.idl"
interface nsIDOMEventTarget;
interface nsIWebNavigation;
interface nsITransferable;
interface nsIDragSession;
interface nsIDOMEvent;
/**
* @status UNDER_REVIEW
*/
/**
* Interfaces for overriding the built-in drag and drop
* implementation in the content area. Use this to do things
* such as prevent a drag from starting, adding or removing
* data and flavors, or preventing the drop.
*/
/**
* Overrides operations at the source of a drag. Can prevent
* drag from starting and can modify what flavors/data are
* presented to the OS.
*/
[scriptable,uuid(e03e6c5e-0d84-4c0b-8739-e6b8d51922de)]
interface nsIOverrideDragSource : nsISupports
{
/**
* Prevents the drag from starting
*
* @param event DOM event (drag gesture)
*
* @return TRUE drag can proceed
* @return FALSE drag is cancelled, does not go to OS
*/
boolean allowStart(in nsIDOMEvent event);
/**
* Alter the flavors or data presented to the OS
*
* @param trans the transferable holding the list of flavors
* and the data for each flavor
*/
void modify(in nsITransferable trans);
};
/**
* Overrides operations at the destination of a drag. Can prevent
* drag from completing and provide an alternative action than
* the built-in behavior for a drop.
*/
[scriptable,uuid(a0ea9862-e2e6-4fd7-8cab-72afeb53c793)]
interface nsIOverrideDropSite : nsISupports
{
/**
* Tells the OS a drop is not allowed on this browser
*
* @param event DOM event (drag over)
* @param session the drag session from which client can get
* the flavors present or the actual data
*
* @return TRUE indicates to OS that if a drop does happen on this
* browser, it will be accepted.
* @return FALSE indicates to OS drop is not allowed. On win32, this
* will change the cursor to "reject".
*/
boolean allowDrop(in nsIDOMEvent event, in nsIDragSession session);
/**
* Provide an alternative action to the built-in behavior when
* something is dropped on the browser
*
* @param event DOM event (drag drop)
* @param trans the transferable holding the list of flavors
* and the data for each flavor
*
* @return TRUE action was handled, do not perform built-in
* behavior
* @return FALSE action was not overridden, do built-in behavior
*/
boolean dropAction(in nsIDOMEvent event, in nsITransferable trans);
};

View File

@ -74,6 +74,7 @@
#include "nsIIOService.h"
#include "nsIFile.h"
#include "nsIWebNavigation.h"
#include "nsIDragDropOverride.h"
NS_IMPL_ADDREF(nsContentAreaDragDrop)
@ -91,7 +92,7 @@ NS_INTERFACE_MAP_END
// nsContentAreaDragDrop ctor
//
nsContentAreaDragDrop::nsContentAreaDragDrop ( )
: mListenerInstalled(PR_FALSE), mNavigator(nsnull)
: mListenerInstalled(PR_FALSE), mNavigator(nsnull), mOverrideDrag(nsnull), mOverrideDrop(nsnull)
{
NS_INIT_REFCNT();
} // ctor
@ -108,13 +109,17 @@ nsContentAreaDragDrop::~nsContentAreaDragDrop ( )
NS_IMETHODIMP
nsContentAreaDragDrop::HookupTo(nsIDOMEventTarget *inAttachPoint, nsIWebNavigation* inNavigator)
nsContentAreaDragDrop::HookupTo(nsIDOMEventTarget *inAttachPoint, nsIWebNavigation* inNavigator,
nsIOverrideDragSource* inOverrideDrag, nsIOverrideDropSite* inOverrideDrop)
{
NS_ASSERTION(inAttachPoint, "Can't hookup Drag Listeners to NULL receiver");
mEventReceiver = do_QueryInterface(inAttachPoint);
NS_ASSERTION(mEventReceiver, "Target doesn't implement nsIDOMEventReceiver as needed");
mNavigator = inNavigator;
mOverrideDrag = inOverrideDrag;
mOverrideDrop = inOverrideDrop;
return AddDragListener();
}
@ -215,7 +220,12 @@ nsContentAreaDragDrop::DragOver(nsIDOMEvent* inEvent)
nsCOMPtr<nsIDragSession> session;
dragService->GetCurrentSession(getter_AddRefs(session));
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;
if ( mOverrideDrop )
mOverrideDrop->AllowDrop(inEvent, session, &dropAllowed);
nsCOMPtr<nsIDOMDocument> sourceDoc;
session->GetSourceDocument(getter_AddRefs(sourceDoc));
nsCOMPtr<nsIDOMDocument> eventDoc;
@ -339,6 +349,14 @@ nsContentAreaDragDrop::DragDrop(nsIDOMEvent* inMouseEvent)
nsresult rv = session->GetData(trans, 0); // again, we only care about the first object
if ( NS_SUCCEEDED(rv) ) {
// if the client has provided an override callback, call it. It may
// still return that we should continue processing.
if ( mOverrideDrop ) {
PRBool actionHandled = PR_FALSE;
if ( NS_SUCCEEDED(mOverrideDrop->DropAction(inMouseEvent, trans, &actionHandled)) )
if ( actionHandled )
return NS_OK;
}
nsXPIDLCString flavor;
nsCOMPtr<nsISupports> dataWrapper;
PRUint32 dataLen = 0;
@ -826,6 +844,15 @@ nsContentAreaDragDrop::DragGesture(nsIDOMEvent* inMouseEvent)
if ( preventDefault )
return NS_OK;
// if the client has provided an override callback, check if we
// should continue
if ( mOverrideDrag ) {
PRBool allow = PR_FALSE;
if ( NS_SUCCEEDED(mOverrideDrag->AllowStart(inMouseEvent, &allow)) )
if ( !allow )
return NS_OK;
}
nsAutoString urlString, titleString, htmlString;
PRBool isAnchor = PR_FALSE;
@ -836,6 +863,11 @@ nsContentAreaDragDrop::DragGesture(nsIDOMEvent* inMouseEvent)
nsCOMPtr<nsITransferable> trans;
nsresult rv = CreateTransferable(urlString, titleString, htmlString, isAnchor, getter_AddRefs(trans));
if ( trans ) {
// if the client has provided an override callback, let them manipulate
// the flavors or drag data
if ( mOverrideDrag )
mOverrideDrag->Modify(trans);
nsCOMPtr<nsISupportsArray> transArray(do_CreateInstance("@mozilla.org/supports-array;1"));
if ( !transArray )
return NS_ERROR_FAILURE;

View File

@ -49,6 +49,8 @@
class nsIDOMNode;
class nsISelection;
class nsITransferable;
class nsIOverrideDragSource;
class nsIOverrideDropSite;
// {1f34bc80-1bc7-11d6-a384-d705dd0746fc}
@ -110,6 +112,8 @@ private:
nsCOMPtr<nsIDOMEventReceiver> mEventReceiver;
nsIWebNavigation* mNavigator; // weak ref, this is probably my owning webshell
nsIOverrideDragSource* mOverrideDrag; // weak, these could own us but probably will outlive us
nsIOverrideDropSite* mOverrideDrop;
}; // class nsContentAreaDragDrop

View File

@ -883,6 +883,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDragDropOverride.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -980,6 +987,11 @@
<PATH>nsIDragDropHandler.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDragDropOverride.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
<TARGET>
@ -1812,6 +1824,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDragDropOverride.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -1909,6 +1928,11 @@
<PATH>nsIDragDropHandler.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDragDropOverride.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
</TARGETLIST>
@ -2033,6 +2057,12 @@
<PATH>nsIDragDropHandler.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIDragDropOverride.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</GROUPLIST>
</PROJECT>

View File

@ -815,7 +815,8 @@ nsDocShellTreeOwner :: AddChromeListeners ( )
GetEventReceiver(mWebBrowser, getter_AddRefs(rcvr));
//nsCOMPtr<nsIDOMWebNavigation> webNav (do_QueryInterface(mWebBrowser));
nsCOMPtr<nsIDOMEventTarget> rcvrTarget(do_QueryInterface(rcvr));
mChromeDragHandler->HookupTo(rcvrTarget, NS_STATIC_CAST(nsIWebNavigation*, mWebBrowser));
mChromeDragHandler->HookupTo(rcvrTarget, NS_STATIC_CAST(nsIWebNavigation*, mWebBrowser),
nsnull, nsnull);
}
}

View File

@ -252,22 +252,25 @@
<constructor>
<![CDATA[
if (!this.hasAttribute("disableHistory")) {
// wire up session history
// XXXdwh On a dynamic skin switch, we should be checking our box object to obtain
// the session history.
this.webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"].createInstance(Components.interfaces.nsISHistory);
try {
if (!this.hasAttribute("disableHistory")) {
// wire up session history
// XXXdwh On a dynamic skin switch, we should be checking our box object to obtain
// the session history.
this.webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"].createInstance(Components.interfaces.nsISHistory);
// wire up global history. the same applies here.
var globalHistory = Components.classes["@mozilla.org/browser/global-history;1"].getService(Components.interfaces.nsIGlobalHistory);
// wire up global history. the same applies here.
var globalHistory = Components.classes["@mozilla.org/browser/global-history;1"].getService(Components.interfaces.nsIGlobalHistory);
this.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).globalHistory = globalHistory;
this.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).globalHistory = globalHistory;
}
}
catch (x) { }
try {
this.mDragDropHandler = Components.classes["@mozilla.org:/content/content-area-dragdrop;1"]
.createInstance(Components.interfaces.nsIDragDropHandler);
if ( this.mDragDropHandler )
mDragDropHandler.hookupTo(this,null);
mDragDropHandler.hookupTo(this,null,null,null);
}
catch (x) { }
]]>