diff --git a/apps/download/test/unit/pick_test.js b/apps/download/test/unit/pick_test.js index ec3f3bd4b33d..4bd8f8c7dfc8 100644 --- a/apps/download/test/unit/pick_test.js +++ b/apps/download/test/unit/pick_test.js @@ -53,8 +53,8 @@ suite('pick.js >', function() { }); sinon.stub(navigator.mozL10n, 'DateTimeFormat', function(date) { return { - fromNow: function(date) { - return 'pretty' + date.toString(); + relativeDate: function(date, useCompactFormat) { + return Promise.resolve('pretty' + date.toString()); } }; }); diff --git a/apps/settings/index.html b/apps/settings/index.html index 36e7e1b203d6..79961472a88f 100644 --- a/apps/settings/index.html +++ b/apps/settings/index.html @@ -79,6 +79,7 @@ + diff --git a/apps/settings/js/downloads/downloads_list.js b/apps/settings/js/downloads/downloads_list.js index e742480effa3..5903bf61c7df 100644 --- a/apps/settings/js/downloads/downloads_list.js +++ b/apps/settings/js/downloads/downloads_list.js @@ -106,9 +106,6 @@ function _append(download) { return _create(download).then((li) => { downloadsContainer.appendChild(li); - if (download.state === 'downloading') { - download.onstatechange = _onDownloadStateChange; - } }); } diff --git a/apps/settings/test/unit/download_formatter_test.js b/apps/settings/test/unit/download_formatter_test.js index 5908b8f7f651..e8b259e492e7 100644 --- a/apps/settings/test/unit/download_formatter_test.js +++ b/apps/settings/test/unit/download_formatter_test.js @@ -1,21 +1,14 @@ -/* global MocksHelper, MockL10n, DownloadFormatter, MockDownload */ +/* global MockL10n, DownloadFormatter, MockDownload */ 'use strict'; require('/shared/test/unit/mocks/mock_download.js'); require('/shared/js/download/download_formatter.js'); -require('/shared/test/unit/mocks/mock_lazy_loader.js'); require('/shared/test/unit/mocks/mock_l10n.js'); suite('DownloadFormatter', function() { var realL10n; - var mocksHelperForDownloadFormatter = new MocksHelper([ - 'LazyLoader' - ]).init(); - - mocksHelperForDownloadFormatter.attachTestHelpers(); - suiteSetup(function() { realL10n = navigator.mozL10n; navigator.mozL10n = MockL10n; @@ -220,11 +213,18 @@ suite('DownloadFormatter', function() { test(' getDate', function(done) { var now = new Date(); var expectedPrettyDate = 'pretty' + now.toString(); + + // We can't use MockLazyLoader here because it cannot chain Promises + window.LazyLoader = { + load: function(imports) { + return Promise.resolve(); + } + }; + sinon.stub(navigator.mozL10n, 'DateTimeFormat', function(date) { return { - fromNow: function(date, useCompactFormat) { - assert.isUndefined(useCompactFormat); - return 'pretty' + date.toString(); + relativeDate: function(date, useCompactFormat) { + return Promise.resolve(expectedPrettyDate); } }; }); diff --git a/shared/js/download/download_formatter.js b/shared/js/download/download_formatter.js index 11954cbb6686..2313c0219972 100644 --- a/shared/js/download/download_formatter.js +++ b/shared/js/download/download_formatter.js @@ -64,20 +64,17 @@ return _getFormattedSize(bytes); }, getDate: function(download) { - return new Promise(function(resolve, reject) { - var date; + var date; - try { - date = download.startTime; - } catch (ex) { - date = new Date(); - console.error(ex); - } + try { + date = download.startTime; + } catch (ex) { + date = new Date(); + console.error(ex); + } - LazyLoader.load(['shared/js/l10n_date.js'], function onload() { - var prettyDate = navigator.mozL10n.DateTimeFormat().fromNow(date); - resolve(prettyDate); - }); + return LazyLoader.load(['shared/js/l10n_date.js']).then(() => { + return navigator.mozL10n.DateTimeFormat().relativeDate(date); }); }, getUUID: function(download) { diff --git a/shared/js/l10n_date.js b/shared/js/l10n_date.js index 8e46d50dd099..ab02337cd04b 100644 --- a/shared/js/l10n_date.js +++ b/shared/js/l10n_date.js @@ -25,6 +25,8 @@ navigator.mozL10n.DateTimeFormat = function(locales, options) { var _ = navigator.mozL10n.get; // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleFormat + // + // Deprecated. Please, use Intl API instead function localeFormat(d, format) { var tokens = format.match(/(%E.|%O.|%.)/g); @@ -120,6 +122,9 @@ navigator.mozL10n.DateTimeFormat = function(locales, options) { /** * Returns a translated string which respresents the * relative time before or after a date. + * + * Deprecated: Please, use relativeDate for now + * * @param {String|Date} time before/after the currentDate. * @param {String} useCompactFormat whether to use a compact display format. * @param {Number} maxDiff returns a formatted date if the diff is greater. @@ -161,10 +166,58 @@ navigator.mozL10n.DateTimeFormat = function(locales, options) { } } + /** + * Async clone of prettyDate. + * Temporary solution while we're waiting for Intl extension to support + * relative dates. + */ + function relativeDate(time, useCompactFormat, maxDiff) { + maxDiff = maxDiff || 86400 * 10; // default = 10 days + + switch (time.constructor) { + case String: // timestamp + time = parseInt(time); + break; + case Date: + time = time.getTime(); + break; + } + + var secDiff = (Date.now() - time) / 1000; + if (isNaN(secDiff)) { + return navigator.mozL10n.formatValue('incorrectDate'); + } + + if (Math.abs(secDiff) > 60) { + // round milliseconds up if difference is over 1 minute so the result is + // closer to what the user would expect (1h59m59s300ms diff should return + // "in 2 hours" instead of "in an hour") + secDiff = secDiff > 0 ? Math.ceil(secDiff) : Math.floor(secDiff); + } + + if (secDiff > maxDiff) { + var dateString = new Date(time).toLocaleString(navigator.languages, { + year: 'numeric', + month: 'numeric', + day: 'numeric' + }); + return Promise.resolve(dateString); + } + + var f = useCompactFormat ? '-short' : '-long'; + var parts = relativeParts(secDiff); + + var affix = secDiff >= 0 ? '-ago' : '-until'; + for (var i in parts) { + return navigator.mozL10n.formatValue(i + affix + f, { value: parts[i]}); + } + } + // API return { localeFormat: localeFormat, fromNow: prettyDate, + relativeDate: relativeDate, relativeParts: relativeParts }; };