api for overriding aspects of content-area drag&drop. r=ccarlen/sr=sfraser/a=shaver. bug# 126069
This commit is contained in:
Родитель
1e38f6165a
Коммит
da9e4223a6
|
@ -13,3 +13,5 @@ nsIPrintProgress.idl
|
|||
nsIPrintStatusFeedback.idl
|
||||
nsIPrintProgressParams.idl
|
||||
nsIDragDropHandler.idl
|
||||
nsIDragDropOverride.idl
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ XPIDLSRCS = \
|
|||
nsIPrintProgressParams.idl \
|
||||
nsIPrintStatusFeedback.idl \
|
||||
nsIDragDropHandler.idl \
|
||||
nsIDragDropOverride.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -66,6 +66,7 @@ XPIDLSRCS= \
|
|||
.\nsIPrintStatusFeedback.idl \
|
||||
.\nsIPrintProgressParams.idl \
|
||||
.\nsIDragDropHandler.idl \
|
||||
.\nsIDragDropOverride.idl \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) { }
|
||||
]]>
|
||||
|
|
Загрузка…
Ссылка в новой задаче