Dropping files onto an XUL application
It's possible to setup drag and drop events to handle dropping files from external applications or OS file managers onto your XUL-based application. First, you need to hook up the basic drag event handlers:
elem.addEventListener("dragover", _dragOver, true);
elem.addEventListener("dragdrop", _dragDrop, true);
Here, elem could be a window or an XUL element. Next, setup the handlers so that files can be dropped on the application:
function _dragOver(aEvent) {
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
var dragSession = dragService.getCurrentSession();
var supported = dragSession.isDataFlavorSupported("text/x-moz-url");
if (!supported)
supported = dragSession.isDataFlavorSupported("application/x-moz-file");
if (supported)
dragSession.canDrop = true;
}
function _dragDrop(aEvent) {
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
var dragSession = dragService.getCurrentSession();
var _ios = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
var uris = new Array();
// If sourceNode is not null, then the drop was from inside the application
if (dragSession.sourceNode)
return;
// Setup a transfer item to retrieve the file data
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
trans.addDataFlavor("text/x-moz-url");
trans.addDataFlavor("application/x-moz-file");
for (var i=0; i<dragSession.numDropItems; i++) {
var uri = null;
dragSession.getData(trans, i);
var flavor = {}, data = {}, length = {};
trans.getAnyTransferData(flavor, data, length);
if (data) {
try {
var str = data.value.QueryInterface(Components.interfaces.nsISupportsString);
}
catch(ex) {
}
if (str) {
uri = _ios.newURI(str.data.split("\n")[0], null, null);
}
else {
var file = data.value.QueryInterface(Components.interfaces.nsIFile);
if (file)
uri = _ios.newFileURI(file);
}
}
if (uri)
uris.push(uri);
}
// Use the array of file URIs
}
The _dragOver function checks the drag data to see if a simple text file or general purpose file types are available. If the file types are present in the drag data, the function returns that dropping the data is allowed. The _dragDrop function retrieves the file URI data from the drag session and creates an array of file URIs that the XUL application can use.
