1 // ========================================================================== 2 // Project: SproutCore Costello - Property Observing Library 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 /** 9 @class 10 11 Implements some standard methods for copying an object. Add this mixin to 12 any object you create that can create a copy of itself. This mixin is 13 added automatically to the built-in array. 14 15 You should generally implement the copy() method to return a copy of the 16 receiver. 17 18 Note that frozenCopy() will only work if you also implement SC.Freezable. 19 20 @since SproutCore 1.0 21 */ 22 SC.Copyable = /** @scope SC.Copyable.prototype */{ 23 24 /** 25 Walk like a duck. Indicates that the object can be copied. 26 27 @type Boolean 28 */ 29 isCopyable: YES, 30 31 /** 32 Override to return a copy of the receiver. Default implementation raises 33 an exception. 34 35 @param deep {Boolean} if true, a deep copy of the object should be made 36 @returns {Object} copy of receiver 37 */ 38 copy: function(deep) { 39 var className = SC._object_className(this.constructor); 40 throw new Error("%@.copy() is not implemented".fmt(className)); 41 }, 42 43 /** 44 If the object implements SC.Freezable, then this will return a new copy 45 if the object is not frozen and the receiver if the object is frozen. 46 47 Raises an exception if you try to call this method on a object that does 48 not support freezing. 49 50 You should use this method whenever you want a copy of a freezable object 51 since a freezable object can simply return itself without actually 52 consuming more memory. 53 54 @returns {Object} copy of receiver or receiver 55 */ 56 frozenCopy: function() { 57 var isFrozen = this.get ? this.get('isFrozen') : this.isFrozen; 58 if (isFrozen === YES) return this; 59 else if (isFrozen === undefined) throw new Error("%@ does not support freezing".fmt(this)); 60 else return this.copy().freeze(); 61 } 62 }; 63 64 // Make Array copyable 65 SC.mixin(Array.prototype, SC.Copyable); 66 /** 67 Override to return a copy of the receiver. Default implementation raises 68 an exception. 69 70 @param deep {Boolean} if true, a deep copy of the object should be made 71 @returns {Object} copy of receiver 72 */ 73 Array.prototype.copy = function(deep) { 74 var ret = this.slice(), idx; 75 if (deep) { 76 idx = ret.length; 77 while (idx--) ret[idx] = SC.copy(ret[idx], true); 78 } 79 return ret; 80 }; 81