/* * Copyright 2018 Scytl Secure Electronic Voting SA * * All rights reserved * * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package */ /* jshint node:true */ 'use strict'; module.exports = { // This function exposes a private one so that the private one can refer to // itself without having to worry about the `this` moving target. leanCopy: leanCopy, // This function will export the working function or an innocuous one // depending on // whether the platform supports object freezing or not. freeze: Object.freeze ? freeze : doNotFreeze, // This function will merge multiple objects into a single object. merge: merge }; /** * Copies an object's properties into another, leaving out functions and * prototypes. * * The function can be used to return objects, or to modify an existing object, * which would then be passed as the second parameter. * * @function leanCopy * @private * @param {Object} * src The object to copy from * @param {Object} * dest The object to copy to * @returns {Object} An object with the same scalar properties as the source, * but stripped of everything else. */ function leanCopy(src, dest) { if ('undefined' === typeof dest) { // Make sure there's a destination object. dest = Object.create(null); } for (var propertyName in src) { // Check whether the property is not inherited. Alternatively, check that // the `hasOwnProperty` method exists, otherwise the property is not // likely to be inherited. if (!src.hasOwnProperty || src.hasOwnProperty(propertyName)) { var property = src[propertyName]; if (typeof property === 'object') { // Copy onto a new prototype-less object, lean as they come. dest[propertyName] = leanCopy(property, Object.create(null)); } else if (typeof property !== 'function') { dest[propertyName] = property; } } } // Return a lean copy of the source object. return dest; } /** * Prohibits an object from being frozen. * * @function doNotFreeze * @private * @param {Object} * target The object not to freeze. * @returns {Object} The object, unfrozen. */ function doNotFreeze(target) { return target; } /** * Protects an object and all its contents against modification. * * @function freeze * @private * @param {Object} * target The object to freeze. * @returns {Object} The object, after being frozen. */ function freeze(target) { // Get all property names var propNames = Object.getOwnPropertyNames(target); // Freeze the object's properties. propNames.forEach(function(name) { var property = target[name]; // Freeze the properties' properties. if (typeof property === 'object' && property !== null) { freeze(property); } }); // Freeze the object itself. return Object.freeze(target); } /** * Merges all of the objects provided as input into a single object. * *

* NOTE This function is a system independent version of the function * Object.assign. * * @function merge * @private * @returns {Object} The merged objects. */ function merge() { var resObj = {}; for (var i = 0; i < arguments.length; i += 1) { var obj = arguments[i], keys = Object.keys(obj); for (var j = 0; j < keys.length; j += 1) { resObj[keys[j]] = obj[keys[j]]; } } return resObj; }