// 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); } }; });