diff --git a/browser/components/downloads/content/download.xml b/browser/components/downloads/content/download.xml
index 4c37d7597115..2ab973aff7d7 100644
--- a/browser/components/downloads/content/download.xml
+++ b/browser/components/downloads/content/download.xml
@@ -33,6 +33,7 @@
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
diff --git a/browser/components/downloads/content/downloads.js b/browser/components/downloads/content/downloads.js
index 21a75cc3bd02..62d6c03b7492 100644
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -921,8 +921,18 @@ DownloadsViewItem.prototype = {
DownloadsCommon.strings.statePaused,
transfer);
} else if (this.dataItem.state == nsIDM.DOWNLOAD_DOWNLOADING) {
+ // We don't show the rate for each download in order to reduce clutter.
+ // The remaining time per download is likely enough information for the
+ // panel.
+ [status] =
+ DownloadUtils.getDownloadStatusNoRate(this.dataItem.currBytes,
+ this.dataItem.maxBytes,
+ this.dataItem.speed,
+ this.lastEstimatedSecondsLeft);
+
+ // We are, however, OK with displaying the rate in the tooltip.
let newEstimatedSecondsLeft;
- [status, newEstimatedSecondsLeft] =
+ [statusTip, newEstimatedSecondsLeft] =
DownloadUtils.getDownloadStatus(this.dataItem.currBytes,
this.dataItem.maxBytes,
this.dataItem.speed,
diff --git a/browser/components/downloads/content/downloadsOverlay.xul b/browser/components/downloads/content/downloadsOverlay.xul
index a957adb9dacb..700212bac763 100644
--- a/browser/components/downloads/content/downloadsOverlay.xul
+++ b/browser/components/downloads/content/downloadsOverlay.xul
@@ -98,7 +98,6 @@
-
-
+
diff --git a/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties b/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
index 19783bfb2540..f92ec27c4c85 100644
--- a/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/downloads/downloads.properties
@@ -50,6 +50,12 @@ downloadsCompleteMsg=All files have finished downloading.
# %1$S transfer progress; %2$S rate number; %3$S rate unit; %4$S time left
# example: 4 minutes left — 1.1 of 11.1 GB (2.2 MB/sec)
statusFormat3=%4$S — %1$S (%2$S %3$S/sec)
+
+# LOCALIZATION NOTE (statusFormatNoRate): — is the "em dash" (long dash)
+# %1$S transfer progress; %2$S time left
+# example: 4 minutes left — 1.1 of 11.1 GB
+statusFormatNoRate=%2$S — %1$S
+
bytes=bytes
kilobyte=KB
megabyte=MB
diff --git a/toolkit/mozapps/downloads/DownloadUtils.jsm b/toolkit/mozapps/downloads/DownloadUtils.jsm
index f0636cf124db..901e194b92d8 100644
--- a/toolkit/mozapps/downloads/DownloadUtils.jsm
+++ b/toolkit/mozapps/downloads/DownloadUtils.jsm
@@ -55,6 +55,7 @@ const kDownloadProperties =
let gStr = {
statusFormat: "statusFormat3",
+ statusFormatNoRate: "statusFormatNoRate",
transferSameUnits: "transferSameUnits2",
transferDiffUnits: "transferDiffUnits2",
transferNoTotal: "transferNoTotal2",
@@ -102,6 +103,63 @@ this.DownloadUtils = {
*/
getDownloadStatus: function DU_getDownloadStatus(aCurrBytes, aMaxBytes,
aSpeed, aLastSec)
+ {
+ let [transfer, timeLeft, newLast, normalizedSpeed]
+ = this._deriveTransferRate(aCurrBytes, aMaxBytes, aSpeed, aLastSec);
+
+ let [rate, unit] = DownloadUtils.convertByteUnits(normalizedSpeed);
+ let params = [transfer, rate, unit, timeLeft];
+ let status = gBundle.formatStringFromName(gStr.statusFormat, params,
+ params.length);
+ return [status, newLast];
+ },
+
+ /**
+ * Generate a status string for a download given its current progress,
+ * total size, speed, last time remaining. The status string contains the
+ * time remaining, as well as the total bytes downloaded. Unlike
+ * getDownloadStatus, it does not include the rate of download.
+ *
+ * @param aCurrBytes
+ * Number of bytes transferred so far
+ * @param [optional] aMaxBytes
+ * Total number of bytes or -1 for unknown
+ * @param [optional] aSpeed
+ * Current transfer rate in bytes/sec or -1 for unknown
+ * @param [optional] aLastSec
+ * Last time remaining in seconds or Infinity for unknown
+ * @return A pair: [download status text, new value of "last seconds"]
+ */
+ getDownloadStatusNoRate:
+ function DU_getDownloadStatusNoRate(aCurrBytes, aMaxBytes, aSpeed,
+ aLastSec)
+ {
+ let [transfer, timeLeft, newLast]
+ = this._deriveTransferRate(aCurrBytes, aMaxBytes, aSpeed, aLastSec);
+
+ let params = [transfer, timeLeft];
+ let status = gBundle.formatStringFromName(gStr.statusFormatNoRate, params,
+ params.length);
+ return [status, newLast];
+ },
+
+ /**
+ * Helper function that returns a transfer string, a time remaining string,
+ * and a new value of "last seconds".
+ * @param aCurrBytes
+ * Number of bytes transferred so far
+ * @param [optional] aMaxBytes
+ * Total number of bytes or -1 for unknown
+ * @param [optional] aSpeed
+ * Current transfer rate in bytes/sec or -1 for unknown
+ * @param [optional] aLastSec
+ * Last time remaining in seconds or Infinity for unknown
+ * @return A triple: [amount transferred string, time remaining string,
+ * new value of "last seconds"]
+ */
+ _deriveTransferRate: function DU__deriveTransferRate(aCurrBytes,
+ aMaxBytes, aSpeed,
+ aLastSec)
{
if (aMaxBytes == null)
aMaxBytes = -1;
@@ -115,13 +173,8 @@ this.DownloadUtils = {
(aMaxBytes - aCurrBytes) / aSpeed : -1;
let transfer = DownloadUtils.getTransferTotal(aCurrBytes, aMaxBytes);
- let [rate, unit] = DownloadUtils.convertByteUnits(aSpeed);
let [timeLeft, newLast] = DownloadUtils.getTimeLeft(seconds, aLastSec);
-
- let params = [transfer, rate, unit, timeLeft];
- let status = gBundle.formatStringFromName(gStr.statusFormat, params,
- params.length);
- return [status, newLast];
+ return [transfer, timeLeft, newLast, aSpeed];
},
/**
diff --git a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
index 9e43bd1eae16..98b7f40ac2be 100644
--- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
+++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -28,15 +28,14 @@ let gDash = DownloadUtils.getDownloadStatus(0)[0].match(/remaining (.) 0 bytes/)
let gVals = [0, 100, 2345, 55555, 982341, 23194134, 1482, 58, 9921949201, 13498132];
-function testStatus(aCurr, aMore, aRate, aTest)
+function testStatus(aFunc, aCurr, aMore, aRate, aTest)
{
dump("Status Test: " + [aCurr, aMore, aRate, aTest] + "\n");
let curr = gVals[aCurr];
let max = curr + gVals[aMore];
let speed = gVals[aRate];
- let [status, last] =
- DownloadUtils.getDownloadStatus(curr, max, speed);
+ let [status, last] = aFunc(curr, max, speed);
if (0) {
dump("testStatus(" + aCurr + ", " + aMore + ", " + aRate + ", [\"" +
@@ -135,35 +134,72 @@ function run_test()
}
}
- testStatus(2, 1, 7, ["A few seconds remaining -- 2.3 of 2.4 KB (58 bytes/sec)", 1.724]);
- testStatus(1, 2, 6, ["A few seconds remaining -- 100 bytes of 2.4 KB (1.4 KB/sec)", 1.582]);
- testStatus(4, 3, 9, ["A few seconds remaining -- 959 KB of 1.0 MB (12.9 MB/sec)", 0.004]);
- testStatus(2, 3, 8, ["A few seconds remaining -- 2.3 of 56.5 KB (9.2 GB/sec)", 0.000]);
+ // First, test with rates, via getDownloadStatus...
+ let statusFunc = DownloadUtils.getDownloadStatus.bind(DownloadUtils);
- testStatus(8, 4, 3, ["17 seconds remaining -- 9.2 of 9.2 GB (54.3 KB/sec)", 17.682]);
- testStatus(1, 3, 2, ["23 seconds remaining -- 100 bytes of 54.4 KB (2.3 KB/sec)", 23.691]);
- testStatus(9, 3, 2, ["23 seconds remaining -- 12.9 of 12.9 MB (2.3 KB/sec)", 23.691]);
- testStatus(5, 6, 7, ["25 seconds remaining -- 22.1 of 22.1 MB (58 bytes/sec)", 25.552]);
+ testStatus(statusFunc, 2, 1, 7, ["A few seconds remaining -- 2.3 of 2.4 KB (58 bytes/sec)", 1.724]);
+ testStatus(statusFunc, 1, 2, 6, ["A few seconds remaining -- 100 bytes of 2.4 KB (1.4 KB/sec)", 1.582]);
+ testStatus(statusFunc, 4, 3, 9, ["A few seconds remaining -- 959 KB of 1.0 MB (12.9 MB/sec)", 0.004]);
+ testStatus(statusFunc, 2, 3, 8, ["A few seconds remaining -- 2.3 of 56.5 KB (9.2 GB/sec)", 0.000]);
- testStatus(3, 9, 3, ["4 minutes remaining -- 54.3 KB of 12.9 MB (54.3 KB/sec)", 242.969]);
- testStatus(2, 3, 1, ["9 minutes remaining -- 2.3 of 56.5 KB (100 bytes/sec)", 555.550]);
- testStatus(4, 3, 7, ["15 minutes remaining -- 959 KB of 1.0 MB (58 bytes/sec)", 957.845]);
- testStatus(5, 3, 7, ["15 minutes remaining -- 22.1 of 22.2 MB (58 bytes/sec)", 957.845]);
+ testStatus(statusFunc, 8, 4, 3, ["17 seconds remaining -- 9.2 of 9.2 GB (54.3 KB/sec)", 17.682]);
+ testStatus(statusFunc, 1, 3, 2, ["23 seconds remaining -- 100 bytes of 54.4 KB (2.3 KB/sec)", 23.691]);
+ testStatus(statusFunc, 9, 3, 2, ["23 seconds remaining -- 12.9 of 12.9 MB (2.3 KB/sec)", 23.691]);
+ testStatus(statusFunc, 5, 6, 7, ["25 seconds remaining -- 22.1 of 22.1 MB (58 bytes/sec)", 25.552]);
- testStatus(1, 9, 2, ["1 hour, 35 minutes remaining -- 100 bytes of 12.9 MB (2.3 KB/sec)", 5756.133]);
- testStatus(2, 9, 6, ["2 hours, 31 minutes remaining -- 2.3 KB of 12.9 MB (1.4 KB/sec)", 9108.051]);
- testStatus(2, 4, 1, ["2 hours, 43 minutes remaining -- 2.3 of 962 KB (100 bytes/sec)", 9823.410]);
- testStatus(6, 4, 7, ["4 hours, 42 minutes remaining -- 1.4 of 961 KB (58 bytes/sec)", 16936.914]);
+ testStatus(statusFunc, 3, 9, 3, ["4 minutes remaining -- 54.3 KB of 12.9 MB (54.3 KB/sec)", 242.969]);
+ testStatus(statusFunc, 2, 3, 1, ["9 minutes remaining -- 2.3 of 56.5 KB (100 bytes/sec)", 555.550]);
+ testStatus(statusFunc, 4, 3, 7, ["15 minutes remaining -- 959 KB of 1.0 MB (58 bytes/sec)", 957.845]);
+ testStatus(statusFunc, 5, 3, 7, ["15 minutes remaining -- 22.1 of 22.2 MB (58 bytes/sec)", 957.845]);
- testStatus(6, 9, 1, ["1 day, 13 hours remaining -- 1.4 KB of 12.9 MB (100 bytes/sec)", 134981.320]);
- testStatus(3, 8, 3, ["2 days, 1 hour remaining -- 54.3 KB of 9.2 GB (54.3 KB/sec)", 178596.872]);
- testStatus(1, 8, 6, ["77 days, 11 hours remaining -- 100 bytes of 9.2 GB (1.4 KB/sec)", 6694972.470]);
- testStatus(6, 8, 7, ["1979 days, 22 hours remaining -- 1.4 KB of 9.2 GB (58 bytes/sec)", 171068089.672]);
+ testStatus(statusFunc, 1, 9, 2, ["1 hour, 35 minutes remaining -- 100 bytes of 12.9 MB (2.3 KB/sec)", 5756.133]);
+ testStatus(statusFunc, 2, 9, 6, ["2 hours, 31 minutes remaining -- 2.3 KB of 12.9 MB (1.4 KB/sec)", 9108.051]);
+ testStatus(statusFunc, 2, 4, 1, ["2 hours, 43 minutes remaining -- 2.3 of 962 KB (100 bytes/sec)", 9823.410]);
+ testStatus(statusFunc, 6, 4, 7, ["4 hours, 42 minutes remaining -- 1.4 of 961 KB (58 bytes/sec)", 16936.914]);
- testStatus(0, 0, 5, ["Unknown time remaining -- 0 of 0 bytes (22.1 MB/sec)", Infinity]);
- testStatus(0, 6, 0, ["Unknown time remaining -- 0 bytes of 1.4 KB (0 bytes/sec)", Infinity]);
- testStatus(6, 6, 0, ["Unknown time remaining -- 1.4 of 2.9 KB (0 bytes/sec)", Infinity]);
- testStatus(8, 5, 0, ["Unknown time remaining -- 9.2 of 9.3 GB (0 bytes/sec)", Infinity]);
+ testStatus(statusFunc, 6, 9, 1, ["1 day, 13 hours remaining -- 1.4 KB of 12.9 MB (100 bytes/sec)", 134981.320]);
+ testStatus(statusFunc, 3, 8, 3, ["2 days, 1 hour remaining -- 54.3 KB of 9.2 GB (54.3 KB/sec)", 178596.872]);
+ testStatus(statusFunc, 1, 8, 6, ["77 days, 11 hours remaining -- 100 bytes of 9.2 GB (1.4 KB/sec)", 6694972.470]);
+ testStatus(statusFunc, 6, 8, 7, ["1979 days, 22 hours remaining -- 1.4 KB of 9.2 GB (58 bytes/sec)", 171068089.672]);
+
+ testStatus(statusFunc, 0, 0, 5, ["Unknown time remaining -- 0 of 0 bytes (22.1 MB/sec)", Infinity]);
+ testStatus(statusFunc, 0, 6, 0, ["Unknown time remaining -- 0 bytes of 1.4 KB (0 bytes/sec)", Infinity]);
+ testStatus(statusFunc, 6, 6, 0, ["Unknown time remaining -- 1.4 of 2.9 KB (0 bytes/sec)", Infinity]);
+ testStatus(statusFunc, 8, 5, 0, ["Unknown time remaining -- 9.2 of 9.3 GB (0 bytes/sec)", Infinity]);
+
+
+ // Now test without rates, via getDownloadStatusNoRate.
+ statusFunc = DownloadUtils.getDownloadStatusNoRate.bind(DownloadUtils);
+
+ testStatus(statusFunc, 2, 1, 7, ["A few seconds remaining -- 2.3 of 2.4 KB", 1.724]);
+ testStatus(statusFunc, 1, 2, 6, ["A few seconds remaining -- 100 bytes of 2.4 KB", 1.582]);
+ testStatus(statusFunc, 4, 3, 9, ["A few seconds remaining -- 959 KB of 1.0 MB", 0.004]);
+ testStatus(statusFunc, 2, 3, 8, ["A few seconds remaining -- 2.3 of 56.5 KB", 0.000]);
+
+ testStatus(statusFunc, 8, 4, 3, ["17 seconds remaining -- 9.2 of 9.2 GB", 17.682]);
+ testStatus(statusFunc, 1, 3, 2, ["23 seconds remaining -- 100 bytes of 54.4 KB", 23.691]);
+ testStatus(statusFunc, 9, 3, 2, ["23 seconds remaining -- 12.9 of 12.9 MB", 23.691]);
+ testStatus(statusFunc, 5, 6, 7, ["25 seconds remaining -- 22.1 of 22.1 MB", 25.552]);
+
+ testStatus(statusFunc, 3, 9, 3, ["4 minutes remaining -- 54.3 KB of 12.9 MB", 242.969]);
+ testStatus(statusFunc, 2, 3, 1, ["9 minutes remaining -- 2.3 of 56.5 KB", 555.550]);
+ testStatus(statusFunc, 4, 3, 7, ["15 minutes remaining -- 959 KB of 1.0 MB", 957.845]);
+ testStatus(statusFunc, 5, 3, 7, ["15 minutes remaining -- 22.1 of 22.2 MB", 957.845]);
+
+ testStatus(statusFunc, 1, 9, 2, ["1 hour, 35 minutes remaining -- 100 bytes of 12.9 MB", 5756.133]);
+ testStatus(statusFunc, 2, 9, 6, ["2 hours, 31 minutes remaining -- 2.3 KB of 12.9 MB", 9108.051]);
+ testStatus(statusFunc, 2, 4, 1, ["2 hours, 43 minutes remaining -- 2.3 of 962 KB", 9823.410]);
+ testStatus(statusFunc, 6, 4, 7, ["4 hours, 42 minutes remaining -- 1.4 of 961 KB", 16936.914]);
+
+ testStatus(statusFunc, 6, 9, 1, ["1 day, 13 hours remaining -- 1.4 KB of 12.9 MB", 134981.320]);
+ testStatus(statusFunc, 3, 8, 3, ["2 days, 1 hour remaining -- 54.3 KB of 9.2 GB", 178596.872]);
+ testStatus(statusFunc, 1, 8, 6, ["77 days, 11 hours remaining -- 100 bytes of 9.2 GB", 6694972.470]);
+ testStatus(statusFunc, 6, 8, 7, ["1979 days, 22 hours remaining -- 1.4 KB of 9.2 GB", 171068089.672]);
+
+ testStatus(statusFunc, 0, 0, 5, ["Unknown time remaining -- 0 of 0 bytes", Infinity]);
+ testStatus(statusFunc, 0, 6, 0, ["Unknown time remaining -- 0 bytes of 1.4 KB", Infinity]);
+ testStatus(statusFunc, 6, 6, 0, ["Unknown time remaining -- 1.4 of 2.9 KB", Infinity]);
+ testStatus(statusFunc, 8, 5, 0, ["Unknown time remaining -- 9.2 of 9.3 GB", Infinity]);
testURI("http://www.mozilla.org/", "mozilla.org", "www.mozilla.org");
testURI("http://www.city.mikasa.hokkaido.jp/", "city.mikasa.hokkaido.jp", "www.city.mikasa.hokkaido.jp");