oop.js revision 4fcbec6145d16637205990699912fb90f6a3807c
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore/**
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * OOP utils. If included, the OOP methods are added to the YUI instance
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @module oop
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam MooreYUI.add("oop", function(Y) {
0a9c6f9f30a66e52ec4ea4ed93504580b3a5669aAdam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore var L = Y.Lang,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore A = Y.Array,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore OP = Object.prototype,
0a9c6f9f30a66e52ec4ea4ed93504580b3a5669aAdam Moore O;
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore /**
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * The following methods are added to the YUI instance
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @class YUI~oop
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore /**
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * Applies prototype properties from the supplier to the receiver.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * The receiver can be a constructor or an instance.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @method augment
9cdb1aa8d3a7901f789c2ad7a6ea00e804a9abebAdam Moore * @param {Function} r the object to receive the augmentation
9cdb1aa8d3a7901f789c2ad7a6ea00e804a9abebAdam Moore * @param {Function} s the object that supplies the properties to augment
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param ov {boolean} if true, properties already on the receiver
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * will be overwritten if found on the supplier.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param wl {string[]} a whitelist. If supplied, only properties in
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * this list will be applied to the receiver.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param args {Array | Any} arg or arguments to apply to the supplier
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * constructor when initializing.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @return {object} the augmented object
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore *
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @todo constructor optional?
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @todo understanding what an instance is augmented with
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @TODO evaluate if we can do this in a way that doesn't interfere
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * with normal inheritance
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.augment = function(r, s, ov, wl, args) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var sProto = s.prototype, newProto = null, construct = s,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore a = (args) ? Y.Array(args) : [], rProto = r.prototype,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore target = rProto || r, applyConstructor = false;
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // working on a class, so apply constructor infrastructure
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore if (rProto && construct) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment will call constructor:');
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.Do.before(r, construct);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore var sequestered = {}, replacements = {};
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore newProto = {};
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // sequester all of the functions in the supplier and replace with
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // one that will restore all of them.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.each(sProto, function(v, k) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // var initialized = false;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore replacements[k] = function() {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var me = this;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore// Y.log('sequestered function "' + k + '" executed. Initializing Event.Target');
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // overwrite the prototype with all of the sequestered functions,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // but only if it hasn't been overridden
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore for (var i in sequestered) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore if (Y.Object.owns(sequestered, i) && (me[i] === replacements[i])) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Y.log('... restoring ' + k);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore me[i] = sequestered[i];
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // apply the constructor
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore construct.apply(me, a);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // apply the original sequestered function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return sequestered[k].apply(me, arguments);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if ((!wl || (k in wl)) && (ov || !(k in this))) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment: ' + k);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (L.isFunction(v)) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // sequester the function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore sequestered[k] = v;
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // replace the sequestered function with a function that will
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // restore all sequestered functions and exectue the constructor.
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore this[k] = replacements[k];
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore } else {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment() applying non-function: ' + k);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore this[k] = v;
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore }
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }, newProto, true);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // augmenting an instance, so apply the constructor immediately
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore } else {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore applyConstructor = true;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.mix(target, newProto || sProto, ov, wl);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (applyConstructor) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore s.apply(target, a);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return r;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore /**
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * Applies object properties from the supplier to the receiver. If
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * the target has the property, and the property is an object, the target
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * object will be augmented with the supplier's value. If the property
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * is an array, the suppliers value will be appended to the target.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @method aggregate
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param {Function} r the object to receive the augmentation
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param {Function} s the object that supplies the properties to augment
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param ov {boolean} if true, properties already on the receiver
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * will be overwritten if found on the supplier.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param wl {string[]} a whitelist. If supplied, only properties in
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * this list will be applied to the receiver.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @return {object} the extended object
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.aggregate = function(r, s, ov, wl) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return Y.mix(r, s, ov, wl, 0, true);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore /**
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * Utility to set up the prototype, constructor and superclass properties to
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * support an inheritance strategy that can chain constructors and methods.
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * Static members will not be inherited.
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore *
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @method extend
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @static
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param {Function} r the object to modify
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param {Function} s the object to inherit
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @param {Object} px prototype properties to add/override
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @param {Object} sx static properties to add/override
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @return {YUI} the YUI instance
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.extend = function(r, s, px, sx) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (!s||!r) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.fail("extend failed, verify dependencies");
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var sp = s.prototype, rp=Y.Object(sp), i;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore r.prototype=rp;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore rp.constructor=r;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore r.superclass=sp;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // If the superclass doesn't have a standard constructor,
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // define one so that Super() works
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (s != Object && sp.constructor == OP.constructor) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore sp.constructor=s;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Add object properties too
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // @TODO removed for now because it isn't that useful and
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // has caused a few issues overwriting things that should
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // not be. You can do this manually if needed. Revisit
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // if this is something that really is needed for some
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // reason.
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Y.mix(r, s);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Add superclass convienience functions
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // @TODO revisit when we have something that works
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.augment(r, Ext);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Add prototype overrides
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore if (px) {
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore Y.mix(rp, px, true);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Add object overrides
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if (sx) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.mix(r, sx, true);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return r;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore /**
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * Executes the supplied function for each item in
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * a collection. Supports arrays, objects, and
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * Y.NodeLists
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @method each
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param o the object to iterate
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param f the function to execute. This function
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * receives the value, key, and object as parameters
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param proto if true, prototype properties are
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * iterated on objects
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @return {YUI} the YUI instance
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore */
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore Y.each = function(o, f, c, proto) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (o.each && o.item) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return o.each.call(o, f, c);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore } else {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore switch (A.test(o)) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore case 1:
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return A.each(o, f, c);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore case 2:
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return A.each(Y.Array(o, 0, true), f, c);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore default:
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return Y.Object.each(o, f, c, proto);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore }
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore }
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore // return Y.Object.each(o, f, c);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore };
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore /**
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * Deep obj/array copy. Functions will are cloned with Y.bind.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * Array-like objects are treated as arrays.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * primitives are returned untouched. Optionally a
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * function can be provided to handle other data types,
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * filter keys, validate values, etc.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore *
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @method clone
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param o what to clone
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param safe {boolean} if true, objects will not have prototype
111837fe5c14f516f4a15878f9bbaf7bb0091364Adam Moore * items from the source. If false, it does. In this case, the
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * original is initally protected, but the clone is not completely immune
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * from changes to the source object prototype. Also, cloned prototype
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * items that are deleted from the clone will result in the value
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * of the source prototype to be exposed. If operating on a non-safe
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * clone, items should be nulled out rather than deleted.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @TODO review
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param f optional function to apply to each item in a collection
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * it will be executed prior to applying the value to
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * the new object. Return false to prevent the copy.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param c optional execution context for f
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @param owner Owner object passed when clone is iterating an
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * object. Used to set up context for cloned functions.
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore * @return {Array|Object} the cloned object
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore */
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore Y.clone = function(o, safe, f, c, owner) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (!L.isObject(o)) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return o;
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore }
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (L.isDate(o)) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return new Date(o);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore }
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore var func = L.isFunction(o), o2;
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (func) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (o instanceof RegExp) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return new RegExp(o.source);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore }
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore o2 = Y.bind(o, owner);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore } else {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore o2 = (safe) ? {} : Y.Object(o);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.each(o, function(v, k) {
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore if (!f || (f.call(c || this, v, k, this, o) !== false)) {
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore this[k] = Y.clone(v, safe, f, c, this);
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore }
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore }, o2);
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore return o2;
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore /**
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore * Returns a function that will execute the supplied function in the
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore * supplied object's context, optionally adding any additional
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore * supplied parameters to the end of the arguments the function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * is executed with.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @TODO review param order for PR2
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @method bind
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param f {Function} the function to bind
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param c the execution context
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @param args* 0..n arguments to append to the arguments collection for the function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore * @return {function} the wrapped function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore */
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.bind = function(f, c) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // if (!f) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('no f');
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // }
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var a = Y.Array(arguments, 2, true);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return function () {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // @todo bind args first, or function args first?
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // return f.apply(c || f, a.concat(Y.Array(arguments, 0, true)));
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore return f.apply(c || f, Y.Array(arguments, 0, true).concat(a));
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore };
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore}, "@VERSION@");
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore