// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// TODO(rginda): Fill out formatTime, add testcases.
cr.define('cr', function() {
/**
* Lookup tables used by bytesToSi.
*/
var units = ['B', 'k', 'M', 'G', 'T', 'P'];
var scale = [1, 1e3, 1e6, 1e9, 1e12, 1e15];
/**
* Construct a new Locale object with a set of strings.
*
* The strings object maps symbolic string names to translated strings
* for the locale. Lists of translated strings are delimited with the caret
* ('^') character.
*
* LOCALE_DAYS_SHORT: List of abbreviated day names.
* LOCALE_MONTHS_SHORT: List of abbreviated month names.
* LOCALE_FMT_SHORT_DATE: A Locale.prototype.formatTime format specifier
* representing the short date format (e.g. Apr 1, 2011) for the
* locale.
*/
function Locale(strings) {
this.dateStrings_ = {
dayShort: strings.LOCALE_DAYS_SHORT.split('^'),
monthShort: strings.LOCALE_MONTHS_SHORT.split('^'),
shortDateFormat: strings.LOCALE_FMT_DATE_SHORT
};
}
Locale.prototype = {
/**
* Convert a number of bytes into an appropriate International System of
* Units (SI) representation, using the correct number separators.
*
* The first time this function is called it computes a lookup table which
* is cached for subsequent calls.
*
* @param {number} bytes The number of bytes.
*/
bytesToSi: function(bytes) {
function fmt(s, u) {
var rounded = Math.round(bytes / s * 10) / 10;
return rounded.toLocaleString() + u;
}
// This loop index is used outside the loop if it turns out |bytes|
// requires the largest unit.
var i;
for (i = 0; i < units.length - 1; i++) {
if (bytes < scale[i + 1])
return fmt(scale[i], units[i]);
}
return fmt(scale[i], units[i]);
},
/**
* Format a date as a string using the given format specifier.
*
* This function is similar to strftime() from the C standard library, with
* the GNU extensions for controlling padding.
*
* The following conversion specifiers are defined:
*
* %% - A literal '%'
* %a - The localized abbreviated weekday name.
* %b - The localized abbreviated month name.
* %d - The day of the month, zero padded (01-31).
* %Y - The four digit year.
*
* Between the '%' character and the conversion specifier character, an
* optional flag and field width may be specified.
*
* The following flag characters are permitted:
* _ (underscore) Pad a numeric result string with spaces.
* - (dash) Do not pad a numeric result string.
* ^ Convert alphabetic characters in result string to upper case.
*
* TODO(rginda): Implement more conversion specifiers.
*
* @param {Date} date The date to be formatted.
* @param {string} spec The format specification.
*/
formatDate: function(date, spec) {
var self = this;
var strings = this.dateStrings_;
// Called back once for each conversion specifier.
function replaceSpecifier(m, flag, width, code) {
// Left pad utility.
function lpad(value, ch) {
value = String(value);
while (width && value.length < width) {
value = ch + value;
}
return value;
}
// Format a value according to the selected flag and field width.
function fmt(value, defaultWidth) {
if (flag == '-') // No padding.
return value;
if (flag == '^') // Convert to uppercase.
value = String(value).toUpperCase();
if (typeof width == 'undefined')
width = defaultWidth;
// If there is no width specifier, there's nothing to pad.
if (!width)
return value;
if (flag == '_') // Pad with spaces.
return lpad(value, ' ');
// Autodetect padding character.
if (typeof value == 'number')
return lpad(value, '0');
return lpad(value, ' ');
}
switch (code) {
case '%': return '%';
case 'a': return fmt(strings.dayShort[date.getDay()]);
case 'b': return fmt(strings.monthShort[date.getMonth()]);
case 'd': return fmt(date.getDate(), 2);
case 'Y': return date.getFullYear();
default:
console.log('Unknown format specifier: ' + code);
return m;
}
}
// Conversion specifiers start with a '%', optionally contain a
// flag and/or field width, followed by a single letter.
// e.g. %a, %-d, %2l.
return spec.replace(/%([\^\-_])?(\d+)?([%a-z])?/gi, replaceSpecifier);
}
};
/**
* Storage for the current cr.locale.
*/
var locale = null;
return {
Locale: Locale,
get locale() {
return locale;
},
initLocale: function(strings) {
locale = new Locale(strings);
}
};
});