mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Uploads manager. Based on the default Downloads Manager.
This commit is contained in:
@@ -108,7 +108,7 @@ sendtophone.checkDrag = function(event)
|
|||||||
|
|
||||||
sendtophone.doDrop = function(event)
|
sendtophone.doDrop = function(event)
|
||||||
{
|
{
|
||||||
var dt = event.dataTransfer
|
var dt = event.dataTransfer;
|
||||||
var types = dt.types;
|
var types = dt.types;
|
||||||
var supportedTypes = ["application/x-moz-file", "text/x-moz-url", "text/uri-list", "text/plain"];
|
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));
|
||||||
@@ -137,10 +137,8 @@ sendtophone.doDrop = function(event)
|
|||||||
for (var i = 0; i < dt.mozItemCount; i++)
|
for (var i = 0; i < dt.mozItemCount; i++)
|
||||||
{
|
{
|
||||||
var file = dt.mozGetDataAt("application/x-moz-file", i);
|
var file = dt.mozGetDataAt("application/x-moz-file", i);
|
||||||
if (file instanceof Components.interfaces.nsIFile )
|
if (file instanceof Ci.nsIFile )
|
||||||
{
|
|
||||||
sendtophoneCore.sendFile(file);
|
sendtophoneCore.sendFile(file);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
this.alert(this.strings.getString("InvalidFile"));
|
this.alert(this.strings.getString("InvalidFile"));
|
||||||
}
|
}
|
||||||
@@ -172,3 +170,4 @@ sendtophone.pickFile = function(folder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
third_party/firefox_sendtophone/chrome/content/upload.css
vendored
Normal file
16
third_party/firefox_sendtophone/chrome/content/upload.css
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
richlistitem[type="upload"][state="0"] {
|
||||||
|
-moz-binding: url('chrome://sendtophone/content/upload.xml#uploading');
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="upload"][state="1"] {
|
||||||
|
-moz-binding: url('chrome://sendtophone/content/upload.xml#compressing');
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only focus buttons in the selected item*/
|
||||||
|
richlistitem[type="upload"]:not([selected="true"]) button {
|
||||||
|
-moz-user-focus: none;
|
||||||
|
}
|
||||||
|
|
||||||
100
third_party/firefox_sendtophone/chrome/content/upload.xml
vendored
Normal file
100
third_party/firefox_sendtophone/chrome/content/upload.xml
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
|
||||||
|
<!DOCTYPE bindings [
|
||||||
|
<!ENTITY % downloadDTD SYSTEM "chrome://sendtophone/locale/uploads.dtd" >
|
||||||
|
%downloadDTD;
|
||||||
|
]>
|
||||||
|
|
||||||
|
<bindings id="uploadBindings"
|
||||||
|
xmlns="http://www.mozilla.org/xbl"
|
||||||
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||||
|
|
||||||
|
<binding id="upload-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||||
|
<resources>
|
||||||
|
<stylesheet src="chrome://sendtophone/skin/uploads.css"/>
|
||||||
|
</resources>
|
||||||
|
<implementation>
|
||||||
|
<property name="inProgress">
|
||||||
|
<getter>
|
||||||
|
<![CDATA[
|
||||||
|
var state = parseInt(this.getAttribute("state"));
|
||||||
|
var currBytes = Number(this.getAttribute("currBytes"));
|
||||||
|
var maxBytes = Number(this.getAttribute("maxBytes"));
|
||||||
|
|
||||||
|
return (state == 0 && (currBytes<maxBytes));
|
||||||
|
]]>
|
||||||
|
</getter>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="buttons">
|
||||||
|
<getter>
|
||||||
|
<![CDATA[
|
||||||
|
var startEl = document.getAnonymousNodes(this);
|
||||||
|
if (!startEl.length)
|
||||||
|
startEl = [this];
|
||||||
|
|
||||||
|
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||||
|
return startEl[0].getElementsByTagNameNS(XULNS, "button");
|
||||||
|
]]>
|
||||||
|
</getter>
|
||||||
|
</property>
|
||||||
|
</implementation>
|
||||||
|
</binding>
|
||||||
|
|
||||||
|
<binding id="uploading" extends="chrome://sendtophone/content/upload.xml#upload-base">
|
||||||
|
<content>
|
||||||
|
<xul:hbox flex="1" class="downloadContentBox">
|
||||||
|
<xul:vbox pack="center">
|
||||||
|
<xul:image class="uploadTypeIcon" validate="always"
|
||||||
|
xbl:inherits="src=image"/>
|
||||||
|
</xul:vbox>
|
||||||
|
<xul:vbox flex="1">
|
||||||
|
<xul:label xbl:inherits="value=target,tooltiptext=file"
|
||||||
|
crop="center" flex="2" class="name"/>
|
||||||
|
<xul:hbox>
|
||||||
|
|
||||||
|
<xul:vbox flex="1">
|
||||||
|
<xul:progressmeter mode="normal" value="0" flex="1"
|
||||||
|
anonid="progressmeter"
|
||||||
|
xbl:inherits="value=progress,mode=progressmode"/>
|
||||||
|
</xul:vbox>
|
||||||
|
<xul:button class="cancel mini-button" tooltiptext="&cmd.cancel.label;"
|
||||||
|
cmd="cmd_cancel" ondblclick="event.stopPropagation();"
|
||||||
|
oncommand="performCommand('cmd_cancel', this);"/>
|
||||||
|
</xul:hbox>
|
||||||
|
<xul:label xbl:inherits="value=status,tooltiptext=statusTip" flex="1"
|
||||||
|
crop="right" class="status"/>
|
||||||
|
<xul:spacer flex="1"/>
|
||||||
|
</xul:vbox>
|
||||||
|
|
||||||
|
</xul:hbox>
|
||||||
|
</content>
|
||||||
|
</binding>
|
||||||
|
|
||||||
|
<binding id="compressing" extends="chrome://sendtophone/content/upload.xml#upload-base">
|
||||||
|
<content>
|
||||||
|
<xul:hbox flex="1">
|
||||||
|
<xul:vbox pack="center">
|
||||||
|
<xul:image class="uploadTypeIcon" validate="always"
|
||||||
|
src="moz-icon://.zip?size=32"/>
|
||||||
|
</xul:vbox>
|
||||||
|
<xul:vbox pack="start" flex="1">
|
||||||
|
<xul:label xbl:inherits="value=target,tooltiptext=file"
|
||||||
|
crop="center" flex="2" class="name"/>
|
||||||
|
|
||||||
|
<xul:hbox>
|
||||||
|
<xul:vbox flex="1">
|
||||||
|
<xul:progressmeter mode="undetermined" flex="1" />
|
||||||
|
</xul:vbox>
|
||||||
|
</xul:hbox>
|
||||||
|
<xul:label value="&compressing.label;" class="status"/>
|
||||||
|
<xul:spacer flex="1"/>
|
||||||
|
</xul:vbox>
|
||||||
|
</xul:hbox>
|
||||||
|
|
||||||
|
</content>
|
||||||
|
</binding>
|
||||||
|
|
||||||
|
</bindings>
|
||||||
160
third_party/firefox_sendtophone/chrome/content/uploads.js
vendored
Normal file
160
third_party/firefox_sendtophone/chrome/content/uploads.js
vendored
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
var Cc = Components.classes;
|
||||||
|
var Ci = Components.interfaces;
|
||||||
|
let Cu = Components.utils;
|
||||||
|
Cu.import("resource://gre/modules/DownloadUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||||
|
|
||||||
|
Cu.import("resource://sendtophone/uploadsManager.js");
|
||||||
|
|
||||||
|
let gUploadManager = sendtophoneUploadsManager;
|
||||||
|
let gUploadsView = null;
|
||||||
|
|
||||||
|
function addFile(upload)
|
||||||
|
{
|
||||||
|
let dl = document.createElement("richlistitem");
|
||||||
|
|
||||||
|
dl.setAttribute("file", upload.file.path);
|
||||||
|
dl.setAttribute("target", upload.file.leafName);
|
||||||
|
dl.setAttribute("image", "moz-icon://" + upload.file.path + "?size=32");
|
||||||
|
|
||||||
|
dl.setAttribute("state", upload.state);
|
||||||
|
dl.setAttribute("startTime", upload.startTime);
|
||||||
|
dl.setAttribute("currBytes", upload.currBytes);
|
||||||
|
dl.setAttribute("maxBytes", upload.maxBytes);
|
||||||
|
dl.setAttribute("lastSeconds", Infinity);
|
||||||
|
|
||||||
|
// Initialize other attributes
|
||||||
|
dl.setAttribute("type", "upload");
|
||||||
|
dl.setAttribute("id", "upl" + upload.id);
|
||||||
|
dl.setAttribute("uploadId", upload.id);
|
||||||
|
|
||||||
|
gUploadsView.appendChild( dl );
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPendingUploads()
|
||||||
|
{
|
||||||
|
if (gUploadsView.children.length==0)
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelUpload(item)
|
||||||
|
{
|
||||||
|
gUploadManager.cancelUpload( parseInt(item.getAttribute("uploadId"), 10) );
|
||||||
|
}
|
||||||
|
|
||||||
|
let gUploadListener = {
|
||||||
|
fileAdded: function(data)
|
||||||
|
{
|
||||||
|
addFile(data);
|
||||||
|
},
|
||||||
|
progressUpdate: function(data)
|
||||||
|
{
|
||||||
|
let item = document.getElementById( "upl" + data.id);
|
||||||
|
item.setAttribute("currBytes", data.currBytes);
|
||||||
|
item.setAttribute("maxBytes", data.maxBytes);
|
||||||
|
|
||||||
|
let percentComplete = Math.round(100 * data.currBytes / data.maxBytes);
|
||||||
|
item.setAttribute("progress", percentComplete);
|
||||||
|
|
||||||
|
// Status text
|
||||||
|
updateStatus(item);
|
||||||
|
},
|
||||||
|
fileFinished: function(data)
|
||||||
|
{
|
||||||
|
let item = document.getElementById("upl" + data.id);
|
||||||
|
gUploadsView.removeChild(item);
|
||||||
|
|
||||||
|
// If no more pending uploads, close the tab.
|
||||||
|
// Use a 100ms timeout to avoid flicker while compress -> upload a folder
|
||||||
|
window.setTimeout( checkPendingUploads, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function Startup()
|
||||||
|
{
|
||||||
|
gUploadsView = document.getElementById("UploadsBox");
|
||||||
|
|
||||||
|
gUploadManager.addListener(gUploadListener);
|
||||||
|
|
||||||
|
for (let id in gUploadManager.uploads)
|
||||||
|
addFile( gUploadManager.uploads[id] );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function Shutdown()
|
||||||
|
{
|
||||||
|
gUploadManager.removeListener(gUploadListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//// Command Updating and Command Handlers
|
||||||
|
|
||||||
|
var gUploadViewController = {
|
||||||
|
isCommandEnabled: function(aCommand, aItem)
|
||||||
|
{
|
||||||
|
let dl = aItem;
|
||||||
|
|
||||||
|
switch (aCommand) {
|
||||||
|
case "cmd_cancel":
|
||||||
|
return dl.inProgress;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
doCommand: function(aCommand, aItem)
|
||||||
|
{
|
||||||
|
if (this.isCommandEnabled(aCommand, aItem))
|
||||||
|
this.commands[aCommand](aItem);
|
||||||
|
},
|
||||||
|
|
||||||
|
commands: {
|
||||||
|
cmd_cancel: function(aSelectedItem) {
|
||||||
|
cancelUpload(aSelectedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to do commands.
|
||||||
|
*
|
||||||
|
* @param aCmd
|
||||||
|
* The command to be performed.
|
||||||
|
* @param aItem
|
||||||
|
* The richlistitem that represents the download that will have the
|
||||||
|
* command performed on it. If this is null, the command is performed on
|
||||||
|
* all downloads. If the item passed in is not a richlistitem that
|
||||||
|
* represents a download, it will walk up the parent nodes until it finds
|
||||||
|
* a DOM node that is.
|
||||||
|
*/
|
||||||
|
function performCommand(aCmd, aItem)
|
||||||
|
{
|
||||||
|
let elm = aItem;
|
||||||
|
|
||||||
|
while (elm.nodeName != "richlistitem" ||
|
||||||
|
elm.getAttribute("type") != "upload")
|
||||||
|
elm = elm.parentNode;
|
||||||
|
|
||||||
|
gUploadViewController.doCommand(aCmd, elm);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStatus(aItem)
|
||||||
|
{
|
||||||
|
let currBytes = Number(aItem.getAttribute("currBytes"));
|
||||||
|
let maxBytes = Number(aItem.getAttribute("maxBytes"));
|
||||||
|
|
||||||
|
let elapsedTime = (Date.now() - Number(aItem.getAttribute("startTime"))) / 1000;
|
||||||
|
// If we don't have an active upload, assume 0 bytes/sec
|
||||||
|
let speed = (currBytes>0) ? currBytes/elapsedTime : 0;
|
||||||
|
let lastSec = Number(aItem.getAttribute("lastSeconds"));
|
||||||
|
|
||||||
|
let status, newLast;
|
||||||
|
[status, newLast] =
|
||||||
|
DownloadUtils.getDownloadStatus(currBytes, maxBytes, speed, lastSec);
|
||||||
|
|
||||||
|
// Update lastSeconds to be the new value
|
||||||
|
aItem.setAttribute("lastSeconds", newLast);
|
||||||
|
|
||||||
|
aItem.setAttribute("status", status);
|
||||||
|
}
|
||||||
31
third_party/firefox_sendtophone/chrome/content/uploads.xul
vendored
Normal file
31
third_party/firefox_sendtophone/chrome/content/uploads.xul
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://sendtophone/content/upload.css"?>
|
||||||
|
<?xml-stylesheet href="chrome://sendtophone/skin/uploads.css"?>
|
||||||
|
|
||||||
|
<!DOCTYPE window SYSTEM "chrome://sendtophone/locale/overlay.dtd">
|
||||||
|
|
||||||
|
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
id="sendtophoneUploadsWindow"
|
||||||
|
onload="Startup();" onunload="Shutdown();"
|
||||||
|
onclose="return closeWindow(false);">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
id="downloadManager" windowtype="Download:Manager"
|
||||||
|
orient="vertical" title="&downloads.title;" statictitle="&downloads.title;"
|
||||||
|
width="&window.width2;" height="&window.height;" screenX="10" screenY="10"
|
||||||
|
persist="width height screenX screenY sizemode"
|
||||||
|
onload="Startup();" onunload="Shutdown();"
|
||||||
|
onclose="return closeWindow(false);">
|
||||||
|
<script type="application/javascript" src="chrome://mozapps/content/downloads/downloads.js"/>
|
||||||
|
<script type="application/javascript" src="chrome://mozapps/content/downloads/DownloadProgressListener.js"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script type="application/javascript" src="chrome://sendtophone/content/uploads.js"/>
|
||||||
|
|
||||||
|
<richlistbox id="UploadsBox" flex="1">
|
||||||
|
</richlistbox>
|
||||||
|
|
||||||
|
</window>
|
||||||
3
third_party/firefox_sendtophone/chrome/locale/en/uploads.dtd
vendored
Normal file
3
third_party/firefox_sendtophone/chrome/locale/en/uploads.dtd
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<!ENTITY compressing.label "Compressing folder">
|
||||||
|
<!ENTITY cmd.cancel.label "Cancel">
|
||||||
|
<!ENTITY cmd.cancel.accesskey "C">
|
||||||
@@ -13,7 +13,7 @@ smstoLink=Número SMS
|
|||||||
mmsLink=Número MMS
|
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=No es un fichero válido.
|
||||||
SendFileToPhone=Envía ficheros al teléfono.
|
SendFileToPhone=Envía ficheros al teléfono.
|
||||||
SendFolderToPhone=Envía una carpeta al teléfono.
|
SendFolderToPhone=Envía una carpeta al teléfono.
|
||||||
qrTitle=QR Image Link
|
qrTitle=Imagen QR
|
||||||
|
|||||||
3
third_party/firefox_sendtophone/chrome/locale/es/uploads.dtd
vendored
Normal file
3
third_party/firefox_sendtophone/chrome/locale/es/uploads.dtd
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<!ENTITY compressing.label "Comprimiendo carpeta">
|
||||||
|
<!ENTITY cmd.cancel.label "Cancelar">
|
||||||
|
<!ENTITY cmd.cancel.accesskey "C">
|
||||||
63
third_party/firefox_sendtophone/chrome/skin/uploads.css
vendored
Normal file
63
third_party/firefox_sendtophone/chrome/skin/uploads.css
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#UploadsBox {
|
||||||
|
-moz-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Upload View Items */
|
||||||
|
richlistitem[type="upload"] {
|
||||||
|
padding: 5px;
|
||||||
|
min-height: 44px !important;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="upload"]:not([selected="true"]):nth-child(odd) {
|
||||||
|
background-color: -moz-oddtreerow;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="upload"] .status {
|
||||||
|
font-size: smaller;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[selected="true"][type="upload"] {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistbox:focus > richlistitem[selected="true"][type="upload"] .status {
|
||||||
|
color: highlighttext;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="upload"] button {
|
||||||
|
-moz-appearance: none;
|
||||||
|
min-height: 16px;
|
||||||
|
min-width: 16px;
|
||||||
|
max-height: 16px;
|
||||||
|
max-width: 16px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 1px 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Images for buttons in the interface
|
||||||
|
*/
|
||||||
|
richlistitem[type="upload"] button {
|
||||||
|
list-style-image: url(chrome://mozapps/skin/downloads/buttons.png);
|
||||||
|
}
|
||||||
|
.cancel {
|
||||||
|
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||||
|
}
|
||||||
|
.cancel:hover {
|
||||||
|
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||||
|
}
|
||||||
|
.cancel:hover:active {
|
||||||
|
-moz-image-region: rect(0px, 48px, 16px, 32px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prevent flickering when changing states */
|
||||||
|
.uploadTypeIcon {
|
||||||
|
min-height: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
-moz-padding-end: 2px;
|
||||||
|
}
|
||||||
@@ -85,6 +85,15 @@ var sendtophoneCore = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// For use while debugging
|
||||||
|
toConsole: function(text)
|
||||||
|
{
|
||||||
|
var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||||
|
.getService(Ci.nsIConsoleService);
|
||||||
|
|
||||||
|
aConsoleService.logStringMessage( text );
|
||||||
|
},
|
||||||
|
|
||||||
processXHR: function(url, method, data, callback)
|
processXHR: function(url, method, data, callback)
|
||||||
{
|
{
|
||||||
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||||
@@ -143,7 +152,8 @@ var sendtophoneCore = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Main function
|
// Main function
|
||||||
// This is the only method that has to be called from outside this module
|
// This is method that has to be called from outside this module
|
||||||
|
// The other available method is sendFile
|
||||||
send: function(title, url, selection)
|
send: function(title, url, selection)
|
||||||
{
|
{
|
||||||
if (!this.sendUrl)
|
if (!this.sendUrl)
|
||||||
@@ -235,12 +245,12 @@ var sendtophoneCore = {
|
|||||||
|
|
||||||
openTab: function(url, successUrl, callback)
|
openTab: function(url, successUrl, callback)
|
||||||
{
|
{
|
||||||
var gBrowser = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
var gBrowser = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||||
.getService(Components.interfaces.nsIWindowWatcher)
|
.getService(Ci.nsIWindowMediator)
|
||||||
.activeWindow
|
.getMostRecentWindow("navigator:browser")
|
||||||
.gBrowser;
|
.gBrowser;
|
||||||
|
|
||||||
var lastTab = gBrowser.tabContainer.selectedIndex;
|
var lastTabIndex = gBrowser.tabContainer.selectedIndex;
|
||||||
var tab = gBrowser.addTab(url);
|
var tab = gBrowser.addTab(url);
|
||||||
gBrowser.selectedTab = tab;
|
gBrowser.selectedTab = tab;
|
||||||
|
|
||||||
@@ -253,9 +263,9 @@ var sendtophoneCore = {
|
|||||||
callback();
|
callback();
|
||||||
|
|
||||||
// Close tab
|
// Close tab
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeTab(c2pTab);
|
||||||
// ReFocus on tab being sent
|
// ReFocus on tab being sent
|
||||||
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTab];
|
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTabIndex];
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
@@ -288,13 +298,20 @@ var sendtophoneCore = {
|
|||||||
if (!this.prefs)
|
if (!this.prefs)
|
||||||
this.init();
|
this.init();
|
||||||
|
|
||||||
|
if (typeof sendtophoneUploadsManager == "undefined")
|
||||||
|
Components.utils.import("resource://sendtophone/uploadsManager.js");
|
||||||
|
|
||||||
if (nsFile.isDirectory())
|
if (nsFile.isDirectory())
|
||||||
{
|
{
|
||||||
|
// There's no progress notification while compressing, only on end.
|
||||||
|
var progressId = sendtophoneUploadsManager.addZip(nsFile);
|
||||||
// Compress the contents to a zip file
|
// Compress the contents to a zip file
|
||||||
zipFolder(nsFile, function(nsZip)
|
zipFolder(nsFile, function(nsZip)
|
||||||
{
|
{
|
||||||
|
sendtophoneUploadsManager.finishedUpload( progressId );
|
||||||
|
|
||||||
// Send the zip and delete it afterwards
|
// Send the zip and delete it afterwards
|
||||||
sendtophoneCore.sendFile(nsZip, function() {/* nsZip.remove(false)*/ });
|
sendtophoneCore.sendFile(nsZip, function() { nsZip.remove(false) });
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
@@ -353,25 +370,46 @@ var sendtophoneCore = {
|
|||||||
|
|
||||||
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||||
.createInstance(Ci.nsIXMLHttpRequest);
|
.createInstance(Ci.nsIXMLHttpRequest);
|
||||||
|
|
||||||
req.open('POST', uri, false);
|
// Show the progress of uploads
|
||||||
|
sendtophoneUploadsManager.addUpload(nsFile, req);
|
||||||
|
|
||||||
|
req.open('POST', uri, true);
|
||||||
|
|
||||||
req.setRequestHeader("Content-length",multiStream.available());
|
req.setRequestHeader("Content-length",multiStream.available());
|
||||||
req.setRequestHeader("Content-type","multipart/form-data; charset: utf-8; boundary="+boundary);
|
req.setRequestHeader("Content-type","multipart/form-data; charset: utf-8; boundary="+boundary);
|
||||||
req.onload = function(event)
|
req.addEventListener("load", function(event)
|
||||||
{
|
{
|
||||||
|
// If there's a callback (to delete temporary files) we call it now
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
|
||||||
var body = event.target.responseXML;
|
var body = event.target.responseXML;
|
||||||
var uploads;
|
var uploads;
|
||||||
if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
|
if (body && (uploads = body.documentElement.getElementsByTagName("upload")))
|
||||||
{
|
{
|
||||||
sendtophoneCore.send(uploadName, uploads[0].firstChild.data, "");
|
var data = uploads[0].firstChild.data;
|
||||||
// If there's a callback (to delete temporary files) we call it now
|
// sendtophoneCore.toConsole(data);
|
||||||
if (callback)
|
sendtophoneCore.send(uploadName, data, "");
|
||||||
callback();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// error.
|
// error.
|
||||||
sendtophoneCore.alert(uri + "\r\n" + event.target.responseText);
|
sendtophoneCore.alert(uri + "\r\n" + event.target.responseText);
|
||||||
}
|
}, false);
|
||||||
|
// Handle errors or aborted uploads
|
||||||
|
req.addEventListener("error", function(evt)
|
||||||
|
{
|
||||||
|
// If there's a callback (to delete temporary files) we call it now
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
}, false);
|
||||||
|
req.addEventListener("abort", function(evt)
|
||||||
|
{
|
||||||
|
// If there's a callback (to delete temporary files) we call it now
|
||||||
|
if (callback)
|
||||||
|
callback();
|
||||||
|
}, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if required for cookies... don't think so.
|
if required for cookies... don't think so.
|
||||||
try {
|
try {
|
||||||
@@ -403,7 +441,7 @@ const PR_EXCL = 0x80;
|
|||||||
function zipFolder(folder, callback)
|
function zipFolder(folder, callback)
|
||||||
{
|
{
|
||||||
// get TMP directory
|
// get TMP directory
|
||||||
var nsFile = Components.classes["@mozilla.org/file/directory_service;1"].
|
var nsFile = Cc["@mozilla.org/file/directory_service;1"].
|
||||||
getService(Ci.nsIProperties).
|
getService(Ci.nsIProperties).
|
||||||
get("TmpD", Ci.nsIFile);
|
get("TmpD", Ci.nsIFile);
|
||||||
|
|
||||||
|
|||||||
172
third_party/firefox_sendtophone/modules/uploadsManager.js
vendored
Normal file
172
third_party/firefox_sendtophone/modules/uploadsManager.js
vendored
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
var EXPORTED_SYMBOLS = ["sendtophoneUploadsManager"];
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
|
||||||
|
var sendtophoneUploadsManager = {
|
||||||
|
uploads: {},
|
||||||
|
_counter : 0,
|
||||||
|
|
||||||
|
_listeners: [],
|
||||||
|
|
||||||
|
// Add a listener that will be called when there's any change on the uploads
|
||||||
|
addListener: function( obj )
|
||||||
|
{
|
||||||
|
this._listeners.push( obj );
|
||||||
|
},
|
||||||
|
|
||||||
|
// Remove an existing listener object
|
||||||
|
removeListener: function( obj )
|
||||||
|
{
|
||||||
|
for(let i=0, listener; listener = this._listeners[i]; i++)
|
||||||
|
{
|
||||||
|
if (obj == listener)
|
||||||
|
{
|
||||||
|
this._listeners.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new upload
|
||||||
|
* nsFile: The file that it's being send
|
||||||
|
* req: the XmlHttpRequest that will send that file
|
||||||
|
*/
|
||||||
|
addUpload: function(nsFile, req)
|
||||||
|
{
|
||||||
|
let id = this._addToUploads( {file:nsFile, req:req, state:0, percent:0,
|
||||||
|
startTime: Date.now(), currBytes: 0, maxBytes: nsFile.fileSize} );
|
||||||
|
|
||||||
|
req.upload.addEventListener("progress", function(evt)
|
||||||
|
{
|
||||||
|
if (evt.lengthComputable) {
|
||||||
|
sendtophoneUploadsManager.updateProgress(id, evt.loaded, evt.total);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
req.upload.addEventListener("load", function(evt)
|
||||||
|
{
|
||||||
|
sendtophoneUploadsManager.updateProgress(id, evt.loaded, evt.total);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
// Clear row when it has finished
|
||||||
|
req.addEventListener("load", function(evt)
|
||||||
|
{
|
||||||
|
sendtophoneUploadsManager.finishedUpload(id);
|
||||||
|
}, false);
|
||||||
|
// If there's an error or it's aborted, finish its tracking.
|
||||||
|
req.addEventListener("error", function(evt)
|
||||||
|
{
|
||||||
|
sendtophoneUploadsManager.finishedUpload(id);
|
||||||
|
}, false);
|
||||||
|
req.addEventListener("abort", function(evt)
|
||||||
|
{
|
||||||
|
sendtophoneUploadsManager.finishedUpload(id);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a zip (it's not an upload, but this way we can show that something is going on)
|
||||||
|
* nsFolder: a nsFile object pointing to the folder being compressed
|
||||||
|
* When the compression has finished, the external code has to call .finishedUpload(id)
|
||||||
|
* with the id returned in this method.
|
||||||
|
*/
|
||||||
|
addZip: function(nsFolder)
|
||||||
|
{
|
||||||
|
return this._addToUploads( {file:nsFolder, state:1} );
|
||||||
|
},
|
||||||
|
|
||||||
|
_addToUploads: function( obj )
|
||||||
|
{
|
||||||
|
this.init();
|
||||||
|
|
||||||
|
// Creates a counter to automatically assign new ids to each upload
|
||||||
|
let id = this._counter++;
|
||||||
|
obj.id = id;
|
||||||
|
this.uploads[id] = obj;
|
||||||
|
|
||||||
|
for(let i=0, listener; listener = this._listeners[i]; i++)
|
||||||
|
listener.fileAdded( obj );
|
||||||
|
|
||||||
|
return id;
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function()
|
||||||
|
{
|
||||||
|
// Open the tab
|
||||||
|
openAndReuseOneTabPerURL("chrome://sendtophone/content/uploads.xul");
|
||||||
|
},
|
||||||
|
|
||||||
|
updateProgress: function(id, loaded, total)
|
||||||
|
{
|
||||||
|
let upload = this.uploads[id];
|
||||||
|
upload.currBytes = loaded;
|
||||||
|
upload.maxBytes = total;
|
||||||
|
|
||||||
|
this._listeners.forEach( function( listener ) {
|
||||||
|
listener.progressUpdate( upload );
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
finishedUpload: function(id)
|
||||||
|
{
|
||||||
|
let upload = this.uploads[id];
|
||||||
|
delete this.uploads[id];
|
||||||
|
|
||||||
|
this._listeners.forEach( function( listener ) {
|
||||||
|
listener.fileFinished( upload );
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelUpload: function(id)
|
||||||
|
{
|
||||||
|
let upload = this.uploads[id];
|
||||||
|
upload.req.abort();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en/Code_snippets/Tabbed_browser#Reusing_tabs
|
||||||
|
function openAndReuseOneTabPerURL(url) {
|
||||||
|
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||||
|
.getService(Components.interfaces.nsIWindowMediator);
|
||||||
|
var browserEnumerator = wm.getEnumerator("navigator:browser");
|
||||||
|
|
||||||
|
// Check each browser instance for our URL
|
||||||
|
var found = false;
|
||||||
|
while (!found && browserEnumerator.hasMoreElements()) {
|
||||||
|
var browserWin = browserEnumerator.getNext();
|
||||||
|
var tabbrowser = browserWin.gBrowser;
|
||||||
|
|
||||||
|
// Check each tab of this browser instance
|
||||||
|
var numTabs = tabbrowser.browsers.length;
|
||||||
|
for (var index = 0; index < numTabs; index++) {
|
||||||
|
var currentBrowser = tabbrowser.getBrowserAtIndex(index);
|
||||||
|
if (url == currentBrowser.currentURI.spec) {
|
||||||
|
|
||||||
|
// The URL is already opened. Select this tab.
|
||||||
|
tabbrowser.selectedTab = tabbrowser.tabContainer.childNodes[index];
|
||||||
|
|
||||||
|
// Focus *this* browser-window
|
||||||
|
browserWin.focus();
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our URL isn't open. Open it now.
|
||||||
|
if (!found) {
|
||||||
|
var recentWindow = wm.getMostRecentWindow("navigator:browser");
|
||||||
|
if (recentWindow) {
|
||||||
|
// Use an existing browser window
|
||||||
|
recentWindow.delayedOpenTab(url, null, null, null, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No browser windows are open, so open a new one.
|
||||||
|
window.open(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user