mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Send folder as a zip. Handle multiple files.
This commit is contained in:
@@ -108,51 +108,67 @@ sendtophone.checkDrag = function(event)
|
|||||||
|
|
||||||
sendtophone.doDrop = function(event)
|
sendtophone.doDrop = function(event)
|
||||||
{
|
{
|
||||||
var types = event.dataTransfer.types;
|
var dt = event.dataTransfer
|
||||||
var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/x-moz-url", "text/plain"];
|
var types = dt.types;
|
||||||
|
var supportedTypes = ["application/x-moz-file", "text/x-moz-url", "text/uri-list", "text/plain"];
|
||||||
types = supportedTypes.filter(function (value) types.contains(value));
|
types = supportedTypes.filter(function (value) types.contains(value));
|
||||||
if (types.length)
|
|
||||||
var plainText = event.dataTransfer.getData(types[0]);
|
|
||||||
var mozUrlArray = event.dataTransfer.getData(types[1]).split("\n");
|
|
||||||
var mozUrl = mozUrlArray[0];
|
|
||||||
var mozTitle = mozUrlArray[1];
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
switch (types[0])
|
switch (types[0])
|
||||||
{
|
{
|
||||||
case "text/plain":
|
case "text/plain":
|
||||||
|
var plainText = dt.getData(types[0]);
|
||||||
sendtophoneCore.send("Selection", "http://google.com", plainText);
|
sendtophoneCore.send("Selection", "http://google.com", plainText);
|
||||||
break;
|
break;
|
||||||
case "text/uri-list":
|
|
||||||
case "text/x-moz-url":
|
case "text/x-moz-url":
|
||||||
|
var mozUrlArray = dt.getData(types[1]).split("\n");
|
||||||
|
var mozUrl = mozUrlArray[0];
|
||||||
|
var mozTitle = mozUrlArray[1] || '';
|
||||||
sendtophoneCore.send(mozTitle, mozUrl, "");
|
sendtophoneCore.send(mozTitle, mozUrl, "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "application/x-moz-file":
|
case "text/uri-list":
|
||||||
var file = event.dataTransfer.mozGetDataAt("application/x-moz-file", 0);
|
var mozUrl = dt.getData(types[0]);
|
||||||
if (file instanceof Components.interfaces.nsIFile && file.isFile() )
|
sendtophoneCore.send("", mozUrl, "");
|
||||||
{
|
break;
|
||||||
var url = Cc["@mozilla.org/network/io-service;1"]
|
|
||||||
.getService(Ci.nsIIOService)
|
|
||||||
.getProtocolHandler("file")
|
|
||||||
.QueryInterface(Ci.nsIFileProtocolHandler)
|
|
||||||
.getURLSpecFromFile(file);
|
|
||||||
|
|
||||||
sendtophoneCore.send("", url, "");
|
case "application/x-moz-file":
|
||||||
|
for (var i = 0; i < dt.mozItemCount; i++)
|
||||||
|
{
|
||||||
|
var file = dt.mozGetDataAt("application/x-moz-file", i);
|
||||||
|
if (file instanceof Components.interfaces.nsIFile )
|
||||||
|
{
|
||||||
|
sendtophoneCore.sendFile(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.alert(this.strings.getString("InvalidFile"));
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
this.alert(this.strings.getString("InvalidFile"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendtophone.sendFile = function()
|
sendtophone.pickFile = function(folder)
|
||||||
{
|
{
|
||||||
var fp = Cc["@mozilla.org/filepicker;1"]
|
var fp = Cc["@mozilla.org/filepicker;1"]
|
||||||
.createInstance(Ci.nsIFilePicker);
|
.createInstance(Ci.nsIFilePicker);
|
||||||
|
|
||||||
fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpen);
|
if (folder)
|
||||||
|
fp.init(window, this.strings.getString("SendFolderToPhone"), Ci.nsIFilePicker.modeGetFolder);
|
||||||
|
else
|
||||||
|
fp.init(window, this.strings.getString("SendFileToPhone"), Ci.nsIFilePicker.modeOpenMultiple);
|
||||||
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages);
|
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterImages);
|
||||||
|
|
||||||
var rv = fp.show();
|
var rv = fp.show();
|
||||||
|
|
||||||
if (rv == Ci.nsIFilePicker.returnOK)
|
if (rv == Ci.nsIFilePicker.returnOK)
|
||||||
sendtophoneCore.send('', fp.fileURL.spec, '');
|
{
|
||||||
|
var files = fp.files;
|
||||||
|
while (files.hasMoreElements())
|
||||||
|
{
|
||||||
|
var file = files.getNext().QueryInterface(Ci.nsILocalFile);
|
||||||
|
sendtophoneCore.sendFile( file );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
<popup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();">
|
<popup id="sendtophoneContextMenu" onpopupshowing="sendtophone.initPopup();">
|
||||||
<menuitem label="&sendtophoneContextSendFile.label;"
|
<menuitem label="&sendtophoneContextSendFile.label;"
|
||||||
accesskey="&sendtophoneContextSendFile.accesskey;"
|
accesskey="&sendtophoneContextSendFile.accesskey;"
|
||||||
oncommand="sendtophone.sendFile()" id="sendtophoneContextMenuSendFile"/>
|
oncommand="sendtophone.pickFile(false)" id="sendtophoneContextMenuSendFile"/>
|
||||||
|
<menuitem label="&sendtophoneContextSendFolder.label;"
|
||||||
|
accesskey="&sendtophoneContextSendFolder.accesskey;"
|
||||||
|
oncommand="sendtophone.pickFile(true)" id="sendtophoneContextMenuSendFolder"/>
|
||||||
<menu label="&sendtophoneProtocols.label;">
|
<menu label="&sendtophoneProtocols.label;">
|
||||||
<menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)">
|
<menupopup id="menu_Protocols" onpopupshowing="sendtophone.onOptionsShowing(this)">
|
||||||
<menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/>
|
<menuitem type="checkbox" id="marketcheck" label="market:" oncommand="sendtophone.onToggleOption(this)" option="market"/>
|
||||||
|
|||||||
@@ -12,5 +12,7 @@
|
|||||||
<!ENTITY sendtophoneContextLogout.accesskey "L">
|
<!ENTITY sendtophoneContextLogout.accesskey "L">
|
||||||
<!ENTITY sendtophoneOptions.title "Send to Phone Preferences">
|
<!ENTITY sendtophoneOptions.title "Send to Phone Preferences">
|
||||||
<!ENTITY sendtophoneProtocols.label "Protocols">
|
<!ENTITY sendtophoneProtocols.label "Protocols">
|
||||||
<!ENTITY sendtophoneContextSendFile.label "Send file...">
|
<!ENTITY sendtophoneContextSendFile.label "Send files...">
|
||||||
<!ENTITY sendtophoneContextSendFile.accesskey "S">
|
<!ENTITY sendtophoneContextSendFile.accesskey "S">
|
||||||
|
<!ENTITY sendtophoneContextSendFolder.label "Send folder...">
|
||||||
|
<!ENTITY sendtophoneContextSendFolder.accesskey "F">
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ mmsLink=MMS Number
|
|||||||
mmstoLink=MMS Number
|
mmstoLink=MMS Number
|
||||||
telLink=Telephone Number
|
telLink=Telephone Number
|
||||||
InvalidFile=Not a valid file
|
InvalidFile=Not a valid file
|
||||||
SendFileToPhone=Send a file to your phone
|
SendFileToPhone=Send files to your phone.
|
||||||
|
SendFolderToPhone=Send a folder to your phone.
|
||||||
|
|||||||
@@ -12,5 +12,7 @@
|
|||||||
<!ENTITY sendtophoneContextLogout.accesskey "L">
|
<!ENTITY sendtophoneContextLogout.accesskey "L">
|
||||||
<!ENTITY sendtophoneOptions.title "Opciones de Send to Phone">
|
<!ENTITY sendtophoneOptions.title "Opciones de Send to Phone">
|
||||||
<!ENTITY sendtophoneProtocols.label "Protocolos">
|
<!ENTITY sendtophoneProtocols.label "Protocolos">
|
||||||
<!ENTITY sendtophoneContextSendFile.label "Enviar fichero...">
|
<!ENTITY sendtophoneContextSendFile.label "Enviar ficheros...">
|
||||||
<!ENTITY sendtophoneContextSendFile.accesskey "E">
|
<!ENTITY sendtophoneContextSendFile.accesskey "E">
|
||||||
|
<!ENTITY sendtophoneContextSendFolder.label "Enviar carpeta...">
|
||||||
|
<!ENTITY sendtophoneContextSendFolder.accesskey "C">
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ mmsLink=Número MMS
|
|||||||
mmstoLink=Número MMS
|
mmstoLink=Número MMS
|
||||||
telLink=Número de teléfono
|
telLink=Número de teléfono
|
||||||
InvalidFile=Solo se puede enviar un fichero cada vez.
|
InvalidFile=Solo se puede enviar un fichero cada vez.
|
||||||
SendFileToPhone=Envía un fichero al teléfono.
|
SendFileToPhone=Envía ficheros al teléfono.
|
||||||
|
SendFolderToPhone=Envía una carpeta al teléfono.
|
||||||
|
|||||||
@@ -87,12 +87,9 @@ var sendtophoneCore = {
|
|||||||
|
|
||||||
processXHR: function(url, method, data, callback)
|
processXHR: function(url, method, data, callback)
|
||||||
{
|
{
|
||||||
if (!this.req)
|
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||||
this.req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
|
||||||
.createInstance(Ci.nsIXMLHttpRequest);
|
.createInstance(Ci.nsIXMLHttpRequest);
|
||||||
|
|
||||||
var req = this.req;
|
|
||||||
|
|
||||||
req.open(method, url, true);
|
req.open(method, url, true);
|
||||||
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
|
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
|
||||||
|
|
||||||
@@ -155,7 +152,12 @@ var sendtophoneCore = {
|
|||||||
// Local files: upload them to a web server
|
// Local files: upload them to a web server
|
||||||
if ((/^file:/i).test(url))
|
if ((/^file:/i).test(url))
|
||||||
{
|
{
|
||||||
this.sendFile(url);
|
var nsFile = Cc["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Ci.nsIIOService)
|
||||||
|
.getProtocolHandler("file")
|
||||||
|
.QueryInterface(Ci.nsIFileProtocolHandler)
|
||||||
|
.getFileFromURLSpec(url);
|
||||||
|
this.sendFile(nsFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,16 +283,28 @@ var sendtophoneCore = {
|
|||||||
return data + converter.Finish();
|
return data + converter.Finish();
|
||||||
},
|
},
|
||||||
|
|
||||||
sendFile: function(fileURL)
|
sendFile: function( nsFile, callback )
|
||||||
{
|
{
|
||||||
var nsFile = Cc["@mozilla.org/network/io-service;1"]
|
if (!this.prefs)
|
||||||
.getService(Ci.nsIIOService)
|
this.init();
|
||||||
.getProtocolHandler("file")
|
|
||||||
.QueryInterface(Ci.nsIFileProtocolHandler)
|
|
||||||
.getFileFromURLSpec(fileURL);
|
|
||||||
|
|
||||||
if (!nsFile.isFile())
|
if (nsFile.isDirectory())
|
||||||
|
{
|
||||||
|
// Compress the contents to a zip file
|
||||||
|
zipFolder(nsFile, function(nsZip)
|
||||||
|
{
|
||||||
|
// Send the zip and delete it afterwards
|
||||||
|
sendtophoneCore.sendFile(nsZip, function() {/* nsZip.remove(false)*/ });
|
||||||
|
}
|
||||||
|
)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nsFile.isFile())
|
||||||
|
{
|
||||||
|
this.alert(this.getString("InvalidFile"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var uploadName = nsFile.leafName;
|
var uploadName = nsFile.leafName;
|
||||||
// Try to determine the MIME type of the file
|
// Try to determine the MIME type of the file
|
||||||
@@ -350,12 +364,16 @@ var sendtophoneCore = {
|
|||||||
if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
|
if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
|
||||||
{
|
{
|
||||||
sendtophoneCore.send(uploadName, uploads[0].firstChild.data, "");
|
sendtophoneCore.send(uploadName, uploads[0].firstChild.data, "");
|
||||||
return
|
// If there's a callback (to delete temporary files) we call it now
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// error.
|
// error.
|
||||||
sendtophoneCore.alert(event.target.responseText);
|
sendtophoneCore.alert(uri + "\r\n" + event.target.responseText);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
if required for cookies... don't think so.
|
||||||
try {
|
try {
|
||||||
req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
|
req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
|
||||||
forceAllowThirdPartyCookie = true;
|
forceAllowThirdPartyCookie = true;
|
||||||
@@ -367,3 +385,69 @@ var sendtophoneCore = {
|
|||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Zipping functions */
|
||||||
|
const PR_RDONLY = 0x01;
|
||||||
|
const PR_WRONLY = 0x02;
|
||||||
|
const PR_RDWR = 0x04;
|
||||||
|
const PR_CREATE_FILE = 0x08;
|
||||||
|
const PR_APPEND = 0x10;
|
||||||
|
const PR_TRUNCATE = 0x20;
|
||||||
|
const PR_SYNC = 0x40;
|
||||||
|
const PR_EXCL = 0x80;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* folder is a nsFile pointing to a folder
|
||||||
|
* callback is a function that it's called after the zip is created. It has one parameter: the nsFile created
|
||||||
|
*/
|
||||||
|
function zipFolder(folder, callback)
|
||||||
|
{
|
||||||
|
// get TMP directory
|
||||||
|
var nsFile = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||||
|
getService(Ci.nsIProperties).
|
||||||
|
get("TmpD", Ci.nsIFile);
|
||||||
|
|
||||||
|
// Create a new file
|
||||||
|
nsFile.append( folder.leafName + ".zip");
|
||||||
|
nsFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||||
|
|
||||||
|
var zipWriter = Components.Constructor("@mozilla.org/zipwriter;1", "nsIZipWriter");
|
||||||
|
var zipW = new zipWriter();
|
||||||
|
|
||||||
|
zipW.open(nsFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
|
||||||
|
|
||||||
|
addFolderContentsToZip(zipW, folder, "");
|
||||||
|
|
||||||
|
// We don't want to block the main thread, so the zipping is done asynchronously
|
||||||
|
// and here we get the notification that it has finished
|
||||||
|
var observer = {
|
||||||
|
onStartRequest: function(request, context) {},
|
||||||
|
onStopRequest: function(request, context, status)
|
||||||
|
{
|
||||||
|
zipW.close();
|
||||||
|
// Notify that we're done. Now it must be sent and deleted afterwards
|
||||||
|
callback(nsFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zipW.processQueue(observer, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function to add the contents of a folder recursively
|
||||||
|
* zipW a nsIZipWriter object
|
||||||
|
* folder a nsFile object pointing to a folder
|
||||||
|
* root a string defining the relative path for this folder in the zip
|
||||||
|
*/
|
||||||
|
function addFolderContentsToZip(zipW, folder, root)
|
||||||
|
{
|
||||||
|
var entries = folder.directoryEntries;
|
||||||
|
while(entries.hasMoreElements())
|
||||||
|
{
|
||||||
|
var entry = entries.getNext();
|
||||||
|
entry.QueryInterface(Ci.nsIFile);
|
||||||
|
zipW.addEntryFile(root + entry.leafName, Ci.nsIZipWriter.COMPRESSION_DEFAULT, entry, true);
|
||||||
|
if (entry.isDirectory())
|
||||||
|
addFolderContentsToZip(zipW, entry, root + entry.leafName + "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user