Skip to content

Commit

Permalink
Fix for MikeMcl#2 - toFormat pollutes the global scope
Browse files Browse the repository at this point in the history
  • Loading branch information
oscsx committed Dec 5, 2018
1 parent a45a742 commit a0de5f1
Showing 1 changed file with 187 additions and 161 deletions.
348 changes: 187 additions & 161 deletions toFormat.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,198 +4,224 @@
* Copyright (c) 2017 Michael Mclaughlin
* MIT Licence
*/

/*
* Adds a `toFormat` method to `Ctor.prototype` and a `format` object to `Ctor`, where `Ctor` is
* a big number constructor such as `Decimal` (decimal.js) or `Big` (big.js).
*/
function toFormat(Ctor) {
;(function (globalScope) {
'use strict';

/*
* Returns a string representing the value of this big number in fixed-point notation to `dp`
* decimal places using rounding mode `rm`, and formatted according to the properties of the
* `fmt`, `this.format` and `this.constructor.format` objects, in that order of precedence.
*
* Example:
*
* x = new Decimal('123456789.987654321')
*
* // Add a format object to the constructor...
* Decimal.format = {
* decimalSeparator: '.',
* groupSeparator: ',',
* groupSize: 3,
* secondaryGroupSize: 0,
* fractionGroupSeparator: '', // '\xA0' non-breaking space
* fractionGroupSize : 0
* }
*
* x.toFormat(); // 123,456,789.987654321
* x.toFormat(2, 1); // 123,456,789.98
*
* // And/or add a format object to the big number itself...
* x.format = {
* decimalSeparator: ',',
* groupSeparator: '',
* }
*
* x.toFormat(); // 123456789,987654321
*
* format = {
* decimalSeparator: '.',
* groupSeparator: ' ',
* groupSize: 3,
* fractionGroupSeparator: ' ', // '\xA0' non-breaking space
* fractionGroupSize : 5
* }
* // And/or pass a format object to the method call.
* x.toFormat(format); // 123 456 789.98765 4321
* x.toFormat(4, format); // 123 456 789.9877
* x.toFormat(2, 1, format); // 123 456 789.98
*
* [dp] {number} Decimal places. Integer.
* [rm] {number} Rounding mode. Integer, 0 to 8. (Ignored if using big.js.)
* [fmt] {Object} A format object.
*
*/
Ctor.prototype.toFormat = function toFormat(dp, rm, fmt) {

if (!this.e && this.e !== 0) return this.toString(); // Infinity/NaN

var arr, g1, g2, i,
u, // undefined
nd, // number of integer digits
intd, // integer digits
intp, // integer part
fracp, // fraction part
dsep, // decimalSeparator
gsep, // groupSeparator
gsize, // groupSize
sgsize, // secondaryGroupSize
fgsep, // fractionGroupSeparator
fgsize, // fractionGroupSize
tfmt = this.format || {},
cfmt = this.constructor.format || {};

if (dp != u) {
if (typeof dp == 'object') {
fmt = dp;
dp = u;
} else if (rm != u) {
if (typeof rm == 'object') {
fmt = rm;
rm = u;
} else if (typeof fmt != 'object') {
* Adds a `toFormat` method to `Ctor.prototype` and a `format` object to `Ctor`, where `Ctor` is
* a big number constructor such as `Decimal` (decimal.js) or `Big` (big.js).
*/
function toFormat(Ctor) {
/*
* Returns a string representing the value of this big number in fixed-point notation to `dp`
* decimal places using rounding mode `rm`, and formatted according to the properties of the
* `fmt`, `this.format` and `this.constructor.format` objects, in that order of precedence.
*
* Example:
*
* x = new Decimal('123456789.987654321')
*
* // Add a format object to the constructor...
* Decimal.format = {
* decimalSeparator: '.',
* groupSeparator: ',',
* groupSize: 3,
* secondaryGroupSize: 0,
* fractionGroupSeparator: '', // '\xA0' non-breaking space
* fractionGroupSize : 0
* }
*
* x.toFormat(); // 123,456,789.987654321
* x.toFormat(2, 1); // 123,456,789.98
*
* // And/or add a format object to the big number itself...
* x.format = {
* decimalSeparator: ',',
* groupSeparator: '',
* }
*
* x.toFormat(); // 123456789,987654321
*
* format = {
* decimalSeparator: '.',
* groupSeparator: ' ',
* groupSize: 3,
* fractionGroupSeparator: ' ', // '\xA0' non-breaking space
* fractionGroupSize : 5
* }
* // And/or pass a format object to the method call.
* x.toFormat(format); // 123 456 789.98765 4321
* x.toFormat(4, format); // 123 456 789.9877
* x.toFormat(2, 1, format); // 123 456 789.98
*
* [dp] {number} Decimal places. Integer.
* [rm] {number} Rounding mode. Integer, 0 to 8. (Ignored if using big.js.)
* [fmt] {Object} A format object.
*
*/
Ctor.prototype.toFormat = function toFormat(dp, rm, fmt) {

if (!this.e && this.e !== 0) return this.toString(); // Infinity/NaN

var arr, g1, g2, i,
u, // undefined
nd, // number of integer digits
intd, // integer digits
intp, // integer part
fracp, // fraction part
dsep, // decimalSeparator
gsep, // groupSeparator
gsize, // groupSize
sgsize, // secondaryGroupSize
fgsep, // fractionGroupSeparator
fgsize, // fractionGroupSize
tfmt = this.format || {},
cfmt = this.constructor.format || {};

if (dp != u) {
if (typeof dp == 'object') {
fmt = dp;
dp = u;
} else if (rm != u) {
if (typeof rm == 'object') {
fmt = rm;
rm = u;
} else if (typeof fmt != 'object') {
fmt = {};
}
} else {
fmt = {};
}
} else {
fmt = {};
}
} else {
fmt = {};
}

arr = this.toFixed(dp, rm).split('.');
intp = arr[0];
fracp = arr[1];
intd = this.s < 0 ? intp.slice(1) : intp;
nd = intd.length;
arr = this.toFixed(dp, rm).split('.');
intp = arr[0];
fracp = arr[1];
intd = this.s < 0 ? intp.slice(1) : intp;
nd = intd.length;

dsep = fmt.decimalSeparator;
if (dsep == u) {
dsep = tfmt.decimalSeparator;
dsep = fmt.decimalSeparator;
if (dsep == u) {
dsep = cfmt.decimalSeparator;
if (dsep == u) dsep = '.';
dsep = tfmt.decimalSeparator;
if (dsep == u) {
dsep = cfmt.decimalSeparator;
if (dsep == u) dsep = '.';
}
}
}

gsep = fmt.groupSeparator;
if (gsep == u) {
gsep = tfmt.groupSeparator;
if (gsep == u) gsep = cfmt.groupSeparator;
}
gsep = fmt.groupSeparator;
if (gsep == u) {
gsep = tfmt.groupSeparator;
if (gsep == u) gsep = cfmt.groupSeparator;
}

if (gsep) {
gsize = fmt.groupSize;
if (gsize == u) {
gsize = tfmt.groupSize;
if (gsep) {
gsize = fmt.groupSize;
if (gsize == u) {
gsize = cfmt.groupSize;
if (gsize == u) gsize = 0;
gsize = tfmt.groupSize;
if (gsize == u) {
gsize = cfmt.groupSize;
if (gsize == u) gsize = 0;
}
}
}

sgsize = fmt.secondaryGroupSize;
if (sgsize == u) {
sgsize = tfmt.secondaryGroupSize;
sgsize = fmt.secondaryGroupSize;
if (sgsize == u) {
sgsize = cfmt.secondaryGroupSize;
if (sgsize == u) sgsize = 0;
sgsize = tfmt.secondaryGroupSize;
if (sgsize == u) {
sgsize = cfmt.secondaryGroupSize;
if (sgsize == u) sgsize = 0;
}
}
}

if (sgsize) {
g1 = +sgsize;
g2 = +gsize;
nd -= g2;
} else {
g1 = +gsize;
g2 = +sgsize;
}
if (sgsize) {
g1 = +sgsize;
g2 = +gsize;
nd -= g2;
} else {
g1 = +gsize;
g2 = +sgsize;
}

if (g1 > 0 && nd > 0) {
i = nd % g1 || g1;
intp = intd.substr(0, i);
for (; i < nd; i += g1) intp += gsep + intd.substr(i, g1);
if (g2 > 0) intp += gsep + intd.slice(i);
if (this.s < 0) intp = '-' + intp;
if (g1 > 0 && nd > 0) {
i = nd % g1 || g1;
intp = intd.substr(0, i);
for (; i < nd; i += g1) intp += gsep + intd.substr(i, g1);
if (g2 > 0) intp += gsep + intd.slice(i);
if (this.s < 0) intp = '-' + intp;
}
}
}

if (fracp) {
fgsep = fmt.fractionGroupSeparator;
if (fgsep == u) {
fgsep = tfmt.fractionGroupSeparator;
if (fgsep == u) fgsep = cfmt.fractionGroupSeparator;
}
if (fracp) {
fgsep = fmt.fractionGroupSeparator;
if (fgsep == u) {
fgsep = tfmt.fractionGroupSeparator;
if (fgsep == u) fgsep = cfmt.fractionGroupSeparator;
}

if (fgsep) {
fgsize = fmt.fractionGroupSize;
if (fgsize == u) {
fgsize = tfmt.fractionGroupSize;
if (fgsep) {
fgsize = fmt.fractionGroupSize;
if (fgsize == u) {
fgsize = cfmt.fractionGroupSize;
if (fgsize == u) fgsize = 0;
fgsize = tfmt.fractionGroupSize;
if (fgsize == u) {
fgsize = cfmt.fractionGroupSize;
if (fgsize == u) fgsize = 0;
}
}
}

fgsize = +fgsize;
fgsize = +fgsize;

if (fgsize) {
fracp = fracp.replace(new RegExp('\\d{' + fgsize + '}\\B', 'g'), '$&' + fgsep);
if (fgsize) {
fracp = fracp.replace(new RegExp('\\d{' + fgsize + '}\\B', 'g'), '$&' + fgsep);
}
}
}

return intp + dsep + fracp;
} else {
return intp + dsep + fracp;
} else {

return intp;
return intp;
}
};

Ctor.format = {
decimalSeparator: '.',
groupSeparator: ',',
groupSize: 3,
secondaryGroupSize: 0,
fractionGroupSeparator: '',
fractionGroupSize: 0
};

return Ctor;
}

// Export.

// AMD.
if (typeof define == 'function' && define.amd) {
define(function (require, exports) {
exports.default = toFormat;
});

// Node and other environments that support module.exports.
} else if (typeof module != 'undefined' && module.exports) {
module.exports = toFormat;

// Browser.
} else {
if (!globalScope) {
globalScope = typeof self != 'undefined' && self && self.self == self ? self : window;
}
};

Ctor.format = {
decimalSeparator: '.',
groupSeparator: ',',
groupSize: 3,
secondaryGroupSize: 0,
fractionGroupSeparator: '',
fractionGroupSize: 0
};
noConflict = globalScope.toFormat;
toFormat.noConflict = function () {
globalScope.toFormat = noConflict;
return toFormat;
};

return Ctor;
}
globalScope.toFormat = toFormat;
}

if (typeof module !== 'undefined' && module.exports) module.exports = toFormat;
})(this);

0 comments on commit a0de5f1

Please sign in to comment.