oop.js revision ee4d8528357b157539bc45a7324cb16d46a88272
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots/**
305beb81428214fbfb7b46543834613f0fbc350eTodd Kloots * Supplies object inheritance and manipulation utilities. This adds
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * additional functionaity to what is provided in yui-base, and the
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * methods are applied directly to the YUI instance. This module
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * is required for most YUI components.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @module oop
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots var L = Y.Lang,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots A = Y.Array,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots OP = Object.prototype;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots /**
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * The following methods are added to the YUI instance
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @class YUI~oop
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots /**
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots * Applies prototype properties from the supplier to the receiver.
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots * The receiver can be a constructor or an instance.
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots * @method augment
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Function} r the object to receive the augmentation
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Function} s the object that supplies the properties to augment
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param ov {boolean} if true, properties already on the receiver
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * will be overwritten if found on the supplier.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param wl {string[]} a whitelist. If supplied, only properties in
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * this list will be applied to the receiver.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param args {Array | Any} arg or arguments to apply to the supplier
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * constructor when initializing.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @return {object} the augmented object
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots *
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @todo constructor optional?
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @todo understanding what an instance is augmented with
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @TODO best practices for overriding sequestered methods.
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots */
aacc7c2be5854cf3e80028d47a46b6e6c39cc7ceTodd Kloots Y.augment = function(r, s, ov, wl, args) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots var sProto = s.prototype, newProto = null, construct = s,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots a = (args) ? Y.Array(args) : [], rProto = r.prototype,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots target = rProto || r, applyConstructor = false;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // working on a class, so apply constructor infrastructure
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (rProto && construct) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots var sequestered = {}, replacements = {};
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots newProto = {};
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // sequester all of the functions in the supplier and replace with
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // one that will restore all of them.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.each(sProto, function(v, k) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots replacements[k] = function() {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots// Y.log('sequestered function "' + k + '" executed. Initializing Event.Target');
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots// overwrite the prototype with all of the sequestered functions,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots// but only if it hasn't been overridden
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots for (var i in sequestered) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (sequestered.hasOwnProperty(i) && (this[i] === replacements[i])) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // Y.log('... restoring ' + k);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots this[i] = sequestered[i];
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots // apply the constructor
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots construct.apply(this, a);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // apply the original sequestered function
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return sequestered[k].apply(this, arguments);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if ((!wl || (k in wl)) && (ov || !(k in this))) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // Y.log('augment: ' + k);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (L.isFunction(v)) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // sequester the function
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots sequestered[k] = v;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots// replace the sequestered function with a function that will
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots// restore all sequestered functions and exectue the constructor.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots this[k] = replacements[k];
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots } else {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // Y.log('augment() applying non-function: ' + k);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots this[k] = v;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }, newProto, true);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // augmenting an instance, so apply the constructor immediately
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots } else {
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots applyConstructor = true;
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.mix(target, newProto || sProto, ov, wl);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (applyConstructor) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots s.apply(target, a);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return r;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots /**
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * Applies object properties from the supplier to the receiver. If
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * the target has the property, and the property is an object, the target
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * object will be augmented with the supplier's value. If the property
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * is an array, the suppliers value will be appended to the target.
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @method aggregate
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param {Function} r the object to receive the augmentation
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Function} s the object that supplies the properties to augment
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param ov {boolean} if true, properties already on the receiver
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * will be overwritten if found on the supplier.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param wl {string[]} a whitelist. If supplied, only properties in
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * this list will be applied to the receiver.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @return {object} the extended object
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.aggregate = function(r, s, ov, wl) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return Y.mix(r, s, ov, wl, 0, true);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots /**
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * Utility to set up the prototype, constructor and superclass properties to
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * support an inheritance strategy that can chain constructors and methods.
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * Static members will not be inherited.
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots *
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @method extend
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Function} r the object to modify
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Function} s the object to inherit
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Object} px prototype properties to add/override
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param {Object} sx static properties to add/override
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @return {YUI} the YUI instance
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.extend = function(r, s, px, sx) {
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots if (!s||!r) {
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots // @TODO error symbols
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots Y.error("extend failed, verify dependencies");
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
30bf1c0f48604e06e2204b98d2e1584c7a8e6f73Satyen Desai var sp = s.prototype, rp=Y.Object(sp), i;
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots r.prototype=rp;
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots rp.constructor=r;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots r.superclass=sp;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // assign constructor property
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (s != Object && sp.constructor == OP.constructor) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots sp.constructor=s;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // add prototype overrides
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (px) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.mix(rp, px, true);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots // add object overrides
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots if (sx) {
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots Y.mix(r, sx, true);
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots }
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots return r;
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots };
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots /**
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * Executes the supplied function for each item in
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * a collection. Supports arrays, objects, and
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * Y.NodeLists
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @method each
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param o the object to iterate
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param f the function to execute. This function
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai * receives the value, key, and object as parameters
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai * @param proto if true, prototype properties are
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai * iterated on objects
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai * @return {YUI} the YUI instance
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai */
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai Y.each = function(o, f, c, proto) {
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai if (o.each && o.item) {
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai return o.each.call(o, f, c);
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai } else {
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai switch (A.test(o)) {
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai case 1:
37c410fc73ed5acc3161813869a31de525b5aa2eSatyen Desai return A.each(o, f, c);
42deb1c29f648a88707554548e596b743749bab2Todd Kloots case 2:
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return A.each(Y.Array(o, 0, true), f, c);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots default:
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return Y.Object.each(o, f, c, proto);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots // return Y.Object.each(o, f, c);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots /**
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * Deep obj/array copy. Functions will are cloned with Y.bind.
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * Array-like objects are treated as arrays.
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * primitives are returned untouched. Optionally a
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots * function can be provided to handle other data types,
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * filter keys, validate values, etc.
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots *
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * @method clone
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots * @param o what to clone
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param safe {boolean} if true, objects will not have prototype
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * items from the source. If false, it does. In this case, the
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * original is initally protected, but the clone is not completely immune
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * from changes to the source object prototype. Also, cloned prototype
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * items that are deleted from the clone will result in the value
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * of the source prototype to be exposed. If operating on a non-safe
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * clone, items should be nulled out rather than deleted.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @TODO review
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param f optional function to apply to each item in a collection
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots * it will be executed prior to applying the value to
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots * the new object. Return false to prevent the copy.
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots * @param c optional execution context for f
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param owner Owner object passed when clone is iterating an
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * object. Used to set up context for cloned functions.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @return {Array|Object} the cloned object
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.clone = function(o, safe, f, c, owner) {
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots if (!L.isObject(o)) {
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots return o;
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots }
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots var o2;
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots switch (L.type(o)) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots case 'date':
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return new Date(o);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots case 'regexp':
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return new RegExp(o.source);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots case 'function':
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots o2 = Y.bind(o, owner);
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots break;
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots case 'array':
09f4dda6dbebf051920fcee4042b242c7c228a4cTodd Kloots o2 = [];
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots break;
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots default:
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots o2 = (safe) ? {} : Y.Object(o);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.each(o, function(v, k) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots if (!f || (f.call(c || this, v, k, this, o) !== false)) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots this[k] = Y.clone(v, safe, f, c, this);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots }, o2);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return o2;
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots /*
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * Returns a function that will execute the supplied function in the
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * supplied object's context, optionally adding any additional
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * supplied parameters to the beginning of the arguments collection the
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * supplied to the function.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots *
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @method bind
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param f {Function} the function to bind
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param c the execution context
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @param args* 0..n arguments to include before the arguments the
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * function is executed with.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @return {function} the wrapped function
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots Y.bind = function(f, c) {
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots var a = Y.Array(arguments, 2, true);
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots return function () {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return f.apply(c || f, a.concat(Y.Array(arguments, 0, true)));
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots /**
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * Returns a function that will execute the supplied function in the
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * supplied object's context, optionally adding any additional
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * supplied parameters to the end of the arguments the function
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * is executed with.
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots *
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * In some cases it is preferable to have the additional arguments
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * applied to the beginning of the function signature. For instance,
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * FireFox setTimeout/setInterval supplies a parameter that other
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * browsers do not.
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * Note: YUI provides a later() function which wraps setTimeout/setInterval,
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * providing context adjustment and parameter addition. This can be
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * used instead of setTimeout/setInterval, avoiding the arguments
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * collection issue when using bind() in FireFox.
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots *
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * @method rbind
0891d75cb3cc23db8fc2846447c429a4015a7afbTodd Kloots * @param f {Function} the function to bind
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param c the execution context
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots * @param args* 0..n arguments to append to the end of arguments collection
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * supplied to the function
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots * @return {function} the wrapped function
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots */
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots Y.rbind = function(f, c) {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots var a = Y.Array(arguments, 2, true);
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return function () {
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots return f.apply(c || f, Y.Array(arguments, 0, true).concat(a));
c9050604e69d834d30facf7b2f64c5762243acbfTodd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots };
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots
0c7476a63b7d7b81ade0fbc59f7b18b15b2fd4c8Todd Kloots