var VnDate = require ('./date'); /** * Checks if two values are equal, it also checks objects. Basic values are * compared using the strict equality operator. * * @param {*} a Value to compare to * @param {*} b Value to compare with * @return {boolean} %true if they are equal, %false otherwise */ function equals (a, b) { if (a === b) return true; if (a instanceof Date && b instanceof Date) return a.getTime () === b.getTime (); if (a && b && (typeof a === 'object') && (typeof b === 'object')) { for (var key in a) if (!equals (a[key], b[key])) return false; for (var key in b) if (a[key] === undefined && b[key] !== undefined) return false; return true; } return false; } /** * Calculates differences between two key-value objects. * * @param {Object} orgObject Value to compare to * @param {Object} newObject Value to compare with * @return {Object} The differences or %null if there are no differences */ function diff (orgObject, newObject) { var diff = {}; for (var key in orgObject) if (!simpleEquals (orgObject[key], newObject[key])) diff[key] = simpleClone (newObject[key]); for (var key in newObject) if (orgObject[key] === undefined && newObject[key] !== undefined) diff[key] = simpleClone (newObject[key]); if (Object.keys (diff).length > 0) return diff; return null; } /** * Calculates new differences between two key-value objects. * * @param {Object} orgObject Value to compare to * @param {Object} newObject Value to compare with * @return {Object} The differences or %null if there are no differences */ function partialDiff (orgObject, newObject) { var diff = {}; for (var key in newObject) if (!simpleEquals (orgObject[key], newObject[key])) diff[key] = simpleClone (newObject[key]); if (Object.keys (diff).length > 0) return diff; return null; } function kvClone (object) { var copy = {}; for (var key in object) copy[key] = simpleClone (object[key]); return copy; } /** * Copies a simple value. * * @param {*} value The value to be copied * @return {*} The value copy */ function simpleClone (value) { if (value instanceof Date) return value.clone (); return value; } /** * Checks if two simple values are equal using the strict equality operator. * * @param {*} a Value to compare to * @param {*} b Value to compare with * @return {boolean} %true if they are equal, %false otherwise */ function simpleEquals (a, b) { if (a === b) return true; if (a instanceof Date && b instanceof Date) return a.getTime () === b.getTime (); return false; } /** * Returns a formated string. * * @param {Object} formatString The base string template * @param {...} arguments Format parameters * @return {string} The formated string */ function sprintf (formatString) { var args = arguments; if (args.length <= 1) return formatString; var i = 1; return formatString.replace (/%[s|d]/g, function () { return args[i++]; }); } module.exports = { regexpNumber: /%\.([0-9]+)d/g ,regexpString: /%s/g ,equals: equals ,diff: diff ,partialDiff: partialDiff ,kvClone: kvClone ,simpleClone: simpleClone ,simpleEquals: simpleEquals ,sprintf: sprintf ,compare: function (a, b) { if (a === b) return true; if (a instanceof Date && b instanceof Date) return a.getTime () === b.getTime (); return false; } ,format: function (value, format) { if (value === null || value === undefined) return ''; if (format) switch (typeof value) { case 'number': return format.replace (this.regexpNumber, this.replaceNumber.bind (null, value)); case 'string': return format.replace (this.regexpString, this.replaceString.bind (null, value)); case 'object': if (value instanceof Date) return VnDate.strftime (value, format); } return value; } ,replaceNumber: function (value, token, digits) { return new Number (value).toFixed (parseInt (digits)); } ,replaceString: function (value) { return value; } };