diff --git a/accounting.js b/accounting.js index 41295f8..2de6d7e 100644 --- a/accounting.js +++ b/accounting.js @@ -1,9 +1,12 @@ /*! - * accounting.js javascript library v0.3.0 - * http://josscrowcroft.github.com/accounting.js/ + * accounting.js v0.4.2 + * Copyright 2014 Open Exchange Rates * - * Copyright 2011 by Joss Crowcroft - * Licensed under GPL v3 | http://www.gnu.org/licenses/gpl-3.0.txt + * Freely distributable under the MIT license. + * Portions of accounting.js are inspired or borrowed from underscore.js + * + * Full details and documentation: + * http://openexchangerates.github.io/accounting.js/ */ (function(root, undefined) { @@ -14,7 +17,7 @@ var lib = {}; // Current version - lib.version = '0.3.0'; + lib.version = '0.4.2'; /* --- Exposed settings --- */ @@ -55,7 +58,7 @@ } /** - * Tests whether supplied parameter is a string + * Tests whether supplied parameter is an array * from underscore.js, delegates to ECMA5's native Array.isArray */ function isArray(obj) { @@ -66,7 +69,7 @@ * Tests whether supplied parameter is a true object */ function isObject(obj) { - return toString.call(obj) === '[object Object]'; + return obj && toString.call(obj) === '[object Object]'; } /** @@ -163,10 +166,11 @@ /** * Takes a string/array of strings, removes all formatting/cruft and returns the raw float value - * alias: accounting.`parse(string)` + * Alias: `accounting.parse(string)` * - * Decimal must be included in the regular expression to match floats (default: "."), so if the number - * uses a non-standard decimal separator, provide it as the second argument. + * Decimal must be included in the regular expression to match floats (defaults to + * accounting.settings.number.decimal), so if the number uses a non-standard decimal + * separator, provide it as the second argument. * * Also matches bracketed negatives (eg. "$ (1.99)" => -1.99) * @@ -186,14 +190,14 @@ // Return the value as-is if it's already a number: if (typeof value === "number") return value; - // Default decimal point is "." but could be set to eg. "," in opts: - decimal = decimal || "."; + // Default decimal point comes from settings, but could be set to eg. "," in opts: + decimal = decimal || lib.settings.number.decimal; // Build regex to strip out everything except digits, decimal point and minus sign: - var regex = new RegExp("[^0-9-" + decimal + "]", ["g"]), + var regex = new RegExp("[^0-9-" + decimal + "]", "g"), unformatted = parseFloat( ("" + value) - .replace(/\((.*)\)/, "-$1") // replace bracketed values with negatives + .replace(/\((?=\d+)(.*)\)/, "-$1") // replace bracketed values with negatives .replace(regex, '') // strip out any cruft .replace(decimal, '.') // make sure decimal point is standard ); @@ -211,20 +215,22 @@ */ var toFixed = lib.toFixed = function(value, precision) { precision = checkPrecision(precision, lib.settings.number.precision); - var power = Math.pow(10, precision); - // Multiply up by precision, round accurately, then divide and use native toFixed(): - return (Math.round(lib.unformat(value) * power) / power).toFixed(precision); + var exponentialForm = Number(lib.unformat(value) + 'e' + precision); + var rounded = Math.round(exponentialForm); + var finalResult = Number(rounded + 'e-' + precision).toFixed(precision); + return finalResult; }; /** * Format a number, with comma-separated thousands and custom precision/decimal places + * Alias: `accounting.format()` * * Localise by overriding the precision and thousand / decimal separators * 2nd parameter `precision` can be an object matching `settings.number` */ - var formatNumber = lib.formatNumber = function(number, precision, thousand, decimal) { + var formatNumber = lib.formatNumber = lib.format = function(number, precision, thousand, decimal) { // Resursively format arrays: if (isArray(number)) { return map(number, function(val) { @@ -261,8 +267,8 @@ /** * Format a number into currency * - * Usage: accounting.formatMoney(number, precision, symbol, thousandsSep, decimalSep, format) - * defaults: (0, 2, "$", ",", ".", "%s%v") + * Usage: accounting.formatMoney(number, symbol, precision, thousandsSep, decimalSep, format) + * defaults: (0, "$", 2, ",", ".", "%s%v") * * Localise by overriding the symbol, precision, thousand / decimal separators and format * Second param can be an object matching `settings.currency` which is the easiest way. @@ -316,7 +322,7 @@ * browsers from collapsing the whitespace in the output strings. */ lib.formatColumn = function(list, symbol, precision, thousand, decimal, format) { - if (!list) return []; + if (!list || !isArray(list)) return []; // Build options object from second param (if object) or all params, extending defaults: var opts = defaults( @@ -375,9 +381,11 @@ // Export accounting for CommonJS. If being loaded as an AMD module, define it as such. // Otherwise, just add `accounting` to the global object - if (typeof module !== 'undefined' && module.exports) { - module.exports = lib; - lib.accounting = lib; + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = lib; + } + exports.accounting = lib; } else if (typeof define === 'function' && define.amd) { // Return the library as an AMD module: define([], function() { diff --git a/accounting.min.js b/accounting.min.js index a4e1a1d..8e09b86 100644 --- a/accounting.min.js +++ b/accounting.min.js @@ -1,2 +1,4 @@ -/* accounting.js v0.3.0 - http://josscrowcroft.github.com/accounting.js */ -(function(p,z){function q(a){return!!(a===""||a&&a.charCodeAt&&a.substr)}function m(a){return u?u(a):v.call(a)==="[object Array]"}function r(a){return v.call(a)==="[object Object]"}function s(a,b){var d,a=a||{},b=b||{};for(d in b)b.hasOwnProperty(d)&&a[d]==null&&(a[d]=b[d]);return a}function j(a,b,d){var c=[],e,h;if(!a)return c;if(w&&a.map===w)return a.map(b,d);for(e=0,h=a.length;e3?g.length%3:0;return f+(l?g.substr(0,l)+e.thousand:"")+g.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+e.thousand)+(h?e.decimal+y(Math.abs(a),h).split(".")[1]:"")},A=c.formatMoney=function(a,b,d,i,e,h){if(m(a))return j(a,function(a){return A(a,b,d,i,e,h)});var a=o(a),f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format);return(a>0?g.pos:a<0?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal))};c.formatColumn=function(a,b,d,i,e,h){if(!a)return[];var f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format),l=g.pos.indexOf("%s")0?g.pos:a<0?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal));if(a.length>k)k=a.length;return a}});return j(a,function(a){return q(a)&&a.lengtha?"-":"",g=parseInt(y(Math.abs(a||0),h),10)+"",l=3a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal))};c.formatColumn=function(a,b,d,i,e,h){if(!a)return[];var f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format),l=g.pos.indexOf("%s")a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal));if(a.length>k)k=a.length;return a});return j(a,function(a){return q(a)&&a.length (https://www.openexchangerates.org)", + "description" : "number, money and currency formatting library", + "homepage" : "http://openexchangerates.github.io/accounting.js", + "ignore" : ["**/.*", "tests"], + "keywords" : ["accounting", "number", "money", "currency", "format", "utilities", "finance", "exchange"], + "main" : "accounting.js", + "name" : "accounting", + "version" : "0.4.2" +} diff --git a/extensions/accounting-jquery.js b/extensions/accounting-jquery.js deleted file mode 100644 index 13f9717..0000000 --- a/extensions/accounting-jquery.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * accounting-jquery.js [alpha] - * - * jQuery plugin wrapper for accounting.js. Dependcies: jQuery, accounting.js (duh) - * Usage: `$(el).accounting("methodName", [opts]);` - */ - -(function($) { - var methods = { - settings: function(options) { - // Merge new options into accounting.settings - accounting.settings = $.extend(true, accounting.settings, options); - - // Return for chaining - return this; - }, - formatNumber: function(options) { - // Apply accounting.formatNumber() to matched elements and return for chaining - return this.each(function() { - $(this).text( - accounting.formatNumber($(this).text(), options) - ); - }); - }, - formatMoney: function(options) { - // Apply accounting.formatMoney() to matched elements and return for chaining - return this.each(function() { - $(this).text( - accounting.formatMoney($(this).text(), options) - ); - }); - }, - formatColumn: function(options) { - var column = []; - - // Collect our values into an array to pass to formatColumn() - this.each(function() { - column.push($(this).text()); - }); - - // Format the column of values - column = accounting.formatColumn(column, options); - - // Now set each of the elements' values and return for chaining - return this.each(function(i) { - $(this).text(column[i]); - }); - }, - toFixed: function(precision) { - // Apply accounting.toFixed() to matched elements and return for chaining - return this.each(function() { - $(this).text( - accounting.toFixed($(this).text(), precision) - ); - }); - }, - unformat: function(decimal) { - // Apply accounting.unformat() to matched elements and return for chaining - return this.each(function() { - $(this).text( - accounting.unformat($(this).text(), decimal) - ); - }); - } - }; - - $.fn.accounting = function(method) { - // Method calling logic - if (methods[method]) { - return methods[method].apply( this, Array.prototype.slice.call(arguments, 1)); - } else if (typeof method === 'object' || !method) { - return methods.settings.apply(this, arguments); - } else { - $.error('Method ' + method + ' does not exist on jQuery.accounting'); - } - }; -})(jQuery); diff --git a/extensions/accounting-units.js b/extensions/accounting-units.js deleted file mode 100644 index 86e5241..0000000 --- a/extensions/accounting-units.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * accounting-units.js [alpha] - * - * Adds a formatUnits method to the accounting.js library (load after accounting.js) - */ - -/** - * Format large values into units (eg. 100K, 12GB) - * - * `base` is the division between units (e.g. 1000 for thousands, 1024 for bytes, etc.) - * `units` is a string or array of strings to apply to each level of division - * (e.g. ["K", "M", "B"] for base 1000) - * `callback` is a function to apply to the value before returning, with the number and the - * relevant unit as params. Can be used to format the number/currency before adding the unit. - * - * Examples (see docs for more info): - * accounting.formatUnits(12345678, 1000, ["K", "M", "B"], function(num, units) { - * return accounting.formatNumber(num, 3) + units; - * }); // "12.346M" - * accounting.formatUnits(123456, 1000000, "M"); // only return millions - * accounting.formatUnits(12345678, 1024, ["KB", "MB", "GB"]); // bytes - */ -accounting.formatUnits = function(number, base, units, callback) { - // Clean up params: - number = accounting.unformat(number); - base = base || 1; - units = typeof units === "string" ? [units] : units || [""]; - - // These are used later: - var unit, - neg = number < 0; - - // If the number is smaller than base, divide it and add the first or only unit: - if ( number < base || base === 1 ) { - number /= base; - unit = units.shift(); - } else { - // Divide number by base until it's smaller than base or has reached the largest unit: - while ( base > 1 && number > Math.abs(base) && units.length ) { - number /= base; - - // Get next unit: - unit = units.shift(); - } - } - - // Apply callback(number, units) to number: - return typeof callback === "function" && callback.call([], number, unit) || number + unit; -}; diff --git a/index.html b/index.html index 79e6564..49aa9d7 100644 --- a/index.html +++ b/index.html @@ -2,9 +2,9 @@ - accounting.js - format money / currency in JavaScript + accounting.js: JavaScript number and currency formatting library - +