oop.js revision 4fcbec6145d16637205990699912fb90f6a3807c
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * OOP utils. If included, the OOP methods are added to the YUI instance
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @module oop
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore A = Y.Array,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * The following methods are added to the YUI instance
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore * @class YUI~oop
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 * @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 var sProto = s.prototype, newProto = null, construct = s,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore a = (args) ? Y.Array(args) : [], rProto = r.prototype,
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // working on a class, so apply constructor infrastructure
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment will call constructor:');
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.Do.before(r, construct);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // sequester all of the functions in the supplier and replace with
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // one that will restore all of them.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // var initialized = false;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore replacements[k] = function() {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore var me = this;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore// Y.log('sequestered function "' + k + '" executed. Initializing Event.Target');
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 // apply the constructor
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // apply the original sequestered function
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore if ((!wl || (k in wl)) && (ov || !(k in this))) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment: ' + k);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // sequester the function
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // replace the sequestered function with a function that will
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // restore all sequestered functions and exectue the constructor.
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('augment() applying non-function: ' + k);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore this[k] = v;
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // augmenting an instance, so apply the constructor immediately
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
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 * @method extend
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 if (!s||!r) {
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 // 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 // Y.mix(r, s);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Add superclass convienience functions
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // @TODO revisit when we have something that works
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.augment(r, Ext);
e69255aa5a65f8406ba2fabaf69fe4e1d05daf69Adam Moore // Add prototype overrides
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Add object overrides
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 switch (A.test(o)) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return A.each(o, f, c);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore // return Y.Object.each(o, f, c);
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 * @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 return new Date(o);
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore if (o instanceof RegExp) {
d1f171a81a8b50c0f694f3dd1ea7ccc08e86cf55Adam Moore return new RegExp(o.source);
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore Y.each(o, function(v, k) {
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore if (!f || (f.call(c || this, v, k, this, o) !== false)) {
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 Y.bind = function(f, c) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // if (!f) {
3641f0baf10c9737e4ac6aac1566bfeaca00eeffAdam Moore // Y.log('no f');
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));
6a3faa9e0e4639febffbd7018ce47b861626d0baAdam Moore}, "@VERSION@");