Skip to content

Instantly share code, notes, and snippets.

@freaktechnik
Created March 9, 2018 22:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freaktechnik/1ad6745b24951e6a6a10b04769ae14d7 to your computer and use it in GitHub Desktop.
Save freaktechnik/1ad6745b24951e6a6a10b04769ae14d7 to your computer and use it in GitHub Desktop.
/* vim: sw=2 ts=2 sts=2 expandtab filetype=javascript
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = [ "RelativeTimeUtils" ];
/**
* This module provides the RelativeTimeUtils object which contains useful methods
* for displaying relative times.
*/
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
const MS_PER_DAY = 24 * 60 * 60 * 1000;
var localeNumberFormatCache = new Map();
function getLocaleNumberFormat(fractionDigits) {
if (!localeNumberFormatCache.has(fractionDigits)) {
localeNumberFormatCache.set(fractionDigits,
new Services.intl.NumberFormat(undefined,
{ maximumFractionDigits: fractionDigits,
minimumFractionDigits: fractionDigits }));
}
return localeNumberFormatCache.get(fractionDigits);
}
const kDownloadProperties =
"chrome://mozapps/locale/downloads/downloads.properties";
var gStr = {
timePair: "timePair2",
timeLeftSingle: "timeLeftSingle2",
timeLeftDouble: "timeLeftDouble2",
timeFewSeconds: "timeFewSeconds",
timeUnknown: "timeUnknown",
yesterday: "yesterday",
// Update timeSize in convertTimeUnits if changing the length of this array
timeUnits: ["seconds", "minutes", "hours", "days"],
};
// This lazily initializes the string bundle upon first use.
Object.defineProperty(this, "gBundle", {
configurable: true,
enumerable: true,
get() {
delete this.gBundle;
return this.gBundle = Services.strings.createBundle(kDownloadProperties);
},
});
var RelativeTimeUtils = {
/**
* Converts a number of seconds to the two largest units. Time values are
* whole numbers, and units have the correct plural/singular form.
*
* @param aSecs
* Seconds to convert into the appropriate 2 units
* @return 4-item array [first value, its unit, second value, its unit]
*/
convertTimeUnits: function DU_convertTimeUnits(aSecs) {
// These are the maximum values for seconds, minutes, hours corresponding
// with gStr.timeUnits without the last item
let timeSize = [60, 60, 24];
let time = aSecs;
let scale = 1;
let unitIndex = 0;
// Keep converting to the next unit while we have units left and the
// current one isn't the largest unit possible
while ((unitIndex < timeSize.length) && (time >= timeSize[unitIndex])) {
time /= timeSize[unitIndex];
scale *= timeSize[unitIndex];
unitIndex++;
}
let value = convertTimeUnitsValue(time);
let units = convertTimeUnitsUnits(value, unitIndex);
let extra = aSecs - value * scale;
let nextIndex = unitIndex - 1;
// Convert the extra time to the next largest unit
for (let index = 0; index < nextIndex; index++)
extra /= timeSize[index];
let value2 = convertTimeUnitsValue(extra);
let units2 = convertTimeUnitsUnits(value2, nextIndex);
return [value, units, value2, units2];
},
};
/**
* Private helper for convertTimeUnits that gets the display value of a time
*
* @param aTime
* Time value for display
* @return An integer value for the time rounded down
*/
function convertTimeUnitsValue(aTime) {
return Math.floor(aTime);
}
/**
* Private helper for convertTimeUnits that gets the display units of a time
*
* @param aTime
* Time value for display
* @param aIndex
* Index into gStr.timeUnits for the appropriate unit
* @return The appropriate plural form of the unit for the time
*/
function convertTimeUnitsUnits(aTime, aIndex) {
// Negative index would be an invalid unit, so just give empty
if (aIndex < 0)
return "";
return PluralForm.get(aTime, gBundle.GetStringFromName(gStr.timeUnits[aIndex]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment