diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 55002f83d..61386a377 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -74,41 +74,49 @@ function difference(object1, object2) { } // clone, just data, no instances of objects -function clone(item) { - if (!item) { return item; } +function clone(item, full) { + if (!item) { return item } // ignore certain objects - var acceptedInstances = [ 'Object', 'Number', 'String', 'Boolean', 'Array' ]; + var acceptedInstances = [ 'Object', 'Number', 'String', 'Boolean', 'Array' ] + if (full) { + acceptedInstances.push( 'Function' ) + } if (item && item.constructor) { if (!_.contains(acceptedInstances, item.constructor.name)) { - return; + return } } - var result; // copy array + var result; if ( _.isArray(item) ) { - result = []; + result = [] item.forEach(function(child, index, array) { - result[index] = clone( child ); + result[index] = clone( child, full ) }); } + // copy function + else if ( _.isFunction(item) ) { + result = item.bind({}) + } + // copy object else if ( _.isObject(item) ) { - result = {}; + result = {} for(var key in item) { if (item.hasOwnProperty(key)) { - result[key] = clone(item[key]) + result[key] = clone( item[key], full ) } } } // copy others else { - result = item; + result = item } - return result; + return result } // taken from http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript diff --git a/public/assets/tests/core.js b/public/assets/tests/core.js index bca6ec2df..82cd9f380 100644 --- a/public/assets/tests/core.js +++ b/public/assets/tests/core.js @@ -486,10 +486,12 @@ test( "clone", function() { var source = [ { name: 'some name' }, { name: 'some name2' }, + { fn: function() { return 'test' } }, ] var reference = [ { name: 'some name' }, { name: 'some name2' }, + { fn: undefined }, ] var result = clone( source ) @@ -498,6 +500,33 @@ test( "clone", function() { deepEqual( result, reference, 'clone' ); + + // full test + var source = [ + { name: 'some name' }, + { name: 'some name2' }, + { fn: function a() { return 'test' } }, + ] + var reference = [ + { name: 'some name' }, + { name: 'some name2' }, + { fn: function a() { return 'test' } }, + ] + var result = clone( source, true ) + + // modify source later, should not have any result + source[0].name = 'some new name' + source[2].fn = 'some new name' + + deepEqual( result[0], reference[0], 'clone full' ); + deepEqual( result[1], reference[1], 'clone full' ); + + equal( typeof reference[2].fn, 'function') + equal( typeof result[2].fn, 'function') + + equal( reference[2].fn(), 'test') + equal( result[2].fn(), 'test') + }); // diff