src/cm/media/js/lib/yui/yui_3.0.0b1/build/oop/oop-debug.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0b1
       
     6 build: 1163
       
     7 */
       
     8 YUI.add('oop', function(Y) {
       
     9 
       
    10 /**
       
    11  * Supplies object inheritance and manipulation utilities.  This adds
       
    12  * additional functionaity to what is provided in yui-base, and the
       
    13  * methods are applied directly to the YUI instance.  This module
       
    14  * is required for most YUI components.
       
    15  * @module oop
       
    16  */
       
    17 
       
    18     var L  = Y.Lang, 
       
    19         A  = Y.Array,
       
    20         OP = Object.prototype;
       
    21 
       
    22     /**
       
    23      * The following methods are added to the YUI instance
       
    24      * @class YUI~oop
       
    25      */
       
    26 
       
    27     /**
       
    28      * Applies prototype properties from the supplier to the receiver.
       
    29      * The receiver can be a constructor or an instance.
       
    30      * @method augment
       
    31      * @param {Function} r  the object to receive the augmentation
       
    32      * @param {Function} s  the object that supplies the properties to augment
       
    33      * @param ov {boolean} if true, properties already on the receiver
       
    34      * will be overwritten if found on the supplier.
       
    35      * @param wl {string[]} a whitelist.  If supplied, only properties in 
       
    36      * this list will be applied to the receiver.
       
    37      * @param args {Array | Any} arg or arguments to apply to the supplier
       
    38      * constructor when initializing.
       
    39      * @return {object} the augmented object
       
    40      *
       
    41      * @todo constructor optional?
       
    42      * @todo understanding what an instance is augmented with
       
    43      * @TODO best practices for overriding sequestered methods.
       
    44      */
       
    45     Y.augment = function(r, s, ov, wl, args) {
       
    46         var sProto           = s.prototype, 
       
    47             newProto         = null, 
       
    48             construct        = s, 
       
    49             a                = (args) ? Y.Array(args) : [], 
       
    50             rProto           = r.prototype, 
       
    51             target           = rProto || r, 
       
    52             applyConstructor = false,
       
    53             sequestered, replacements, i;
       
    54 
       
    55         // working on a class, so apply constructor infrastructure
       
    56         if (rProto && construct) {
       
    57             sequestered  = {};
       
    58             replacements = {};
       
    59             newProto     = {};
       
    60 
       
    61             // sequester all of the functions in the supplier and replace with
       
    62             // one that will restore all of them.
       
    63             Y.each(sProto, function(v, k) {
       
    64                 replacements[k] = function() {
       
    65 
       
    66 // Y.log('sequestered function "' + k + '" executed.  Initializing EventTarget');
       
    67 // overwrite the prototype with all of the sequestered functions,
       
    68 // but only if it hasn't been overridden
       
    69                     for (i in sequestered) {
       
    70                         if (sequestered.hasOwnProperty(i) && (this[i] === replacements[i])) {
       
    71                             // Y.log('... restoring ' + k);
       
    72                             this[i] = sequestered[i];
       
    73                         }
       
    74                     }
       
    75 
       
    76                     // apply the constructor
       
    77                     construct.apply(this, a);
       
    78 
       
    79                     // apply the original sequestered function
       
    80                     return sequestered[k].apply(this, arguments);
       
    81                 };
       
    82 
       
    83                 if ((!wl || (k in wl)) && (ov || !(k in this))) {
       
    84                     // Y.log('augment: ' + k);
       
    85                     if (L.isFunction(v)) {
       
    86                         // sequester the function
       
    87                         sequestered[k] = v;
       
    88 
       
    89 // replace the sequestered function with a function that will
       
    90 // restore all sequestered functions and exectue the constructor.
       
    91                         this[k] = replacements[k];
       
    92                     } else {
       
    93                         // Y.log('augment() applying non-function: ' + k);
       
    94                         this[k] = v;
       
    95                     }
       
    96 
       
    97                 }
       
    98 
       
    99             }, newProto, true);
       
   100 
       
   101         // augmenting an instance, so apply the constructor immediately
       
   102         } else {
       
   103             applyConstructor = true;
       
   104         }
       
   105 
       
   106         Y.mix(target, newProto || sProto, ov, wl);
       
   107 
       
   108         if (applyConstructor) {
       
   109             s.apply(target, a);
       
   110         }
       
   111 
       
   112         return r;
       
   113     };
       
   114 
       
   115     /**
       
   116      * Applies object properties from the supplier to the receiver.  If
       
   117      * the target has the property, and the property is an object, the target
       
   118      * object will be augmented with the supplier's value.  If the property
       
   119      * is an array, the suppliers value will be appended to the target.
       
   120      * @method aggregate
       
   121      * @param {Function} r  the object to receive the augmentation
       
   122      * @param {Function} s  the object that supplies the properties to augment
       
   123      * @param ov {boolean} if true, properties already on the receiver
       
   124      * will be overwritten if found on the supplier.
       
   125      * @param wl {string[]} a whitelist.  If supplied, only properties in 
       
   126      * this list will be applied to the receiver.
       
   127      * @return {object} the extended object
       
   128      */
       
   129     Y.aggregate = function(r, s, ov, wl) {
       
   130         return Y.mix(r, s, ov, wl, 0, true);
       
   131     };
       
   132 
       
   133     /**
       
   134      * Utility to set up the prototype, constructor and superclass properties to
       
   135      * support an inheritance strategy that can chain constructors and methods.
       
   136      * Static members will not be inherited.
       
   137      *
       
   138      * @method extend
       
   139      * @param {Function} r   the object to modify
       
   140      * @param {Function} s the object to inherit
       
   141      * @param {Object} px prototype properties to add/override
       
   142      * @param {Object} sx static properties to add/override
       
   143      * @return {YUI} the YUI instance
       
   144      */
       
   145     Y.extend = function(r, s, px, sx) {
       
   146         if (!s||!r) {
       
   147             // @TODO error symbols
       
   148             Y.error("extend failed, verify dependencies");
       
   149         }
       
   150 
       
   151         var sp = s.prototype, rp=Y.Object(sp);
       
   152         r.prototype=rp;
       
   153 
       
   154         rp.constructor=r;
       
   155         r.superclass=sp;
       
   156 
       
   157         // assign constructor property
       
   158         if (s != Object && sp.constructor == OP.constructor) {
       
   159             sp.constructor=s;
       
   160         }
       
   161     
       
   162         // add prototype overrides
       
   163         if (px) {
       
   164             Y.mix(rp, px, true);
       
   165         }
       
   166 
       
   167         // add object overrides
       
   168         if (sx) {
       
   169             Y.mix(r, sx, true);
       
   170         }
       
   171 
       
   172         return r;
       
   173     };
       
   174 
       
   175     /**
       
   176      * Executes the supplied function for each item in
       
   177      * a collection.  Supports arrays, objects, and
       
   178      * Y.NodeLists
       
   179      * @method each
       
   180      * @param o the object to iterate
       
   181      * @param f the function to execute.  This function
       
   182      * receives the value, key, and object as parameters
       
   183      * @param proto if true, prototype properties are
       
   184      * iterated on objects
       
   185      * @return {YUI} the YUI instance
       
   186      */
       
   187     Y.each = function(o, f, c, proto) {
       
   188 
       
   189         if (o.each && o.item) {
       
   190             return o.each.call(o, f, c);
       
   191         } else {
       
   192             switch (A.test(o)) {
       
   193                 case 1:
       
   194                     return A.each(o, f, c);
       
   195                 case 2:
       
   196                     return A.each(Y.Array(o, 0, true), f, c);
       
   197                 default:
       
   198                     return Y.Object.each(o, f, c, proto);
       
   199             }
       
   200         }
       
   201 
       
   202         // return Y.Object.each(o, f, c);
       
   203     };
       
   204 
       
   205     /**
       
   206      * Deep obj/array copy.  Functions will are cloned with Y.bind.
       
   207      * Array-like objects are treated as arrays.
       
   208      * primitives are returned untouched.  Optionally a
       
   209      * function can be provided to handle other data types,
       
   210      * filter keys, validate values, etc.
       
   211      *
       
   212      * @method clone
       
   213      * @param o what to clone
       
   214      * @param safe {boolean} if true, objects will not have prototype
       
   215      * items from the source.  If false, it does.  In this case, the
       
   216      * original is initally protected, but the clone is not completely immune
       
   217      * from changes to the source object prototype.  Also, cloned prototype
       
   218      * items that are deleted from the clone will result in the value
       
   219      * of the source prototype to be exposed.  If operating on a non-safe
       
   220      * clone, items should be nulled out rather than deleted.
       
   221      * @TODO review
       
   222      * @param f optional function to apply to each item in a collection
       
   223      *          it will be executed prior to applying the value to
       
   224      *          the new object.  Return false to prevent the copy.
       
   225      * @param c optional execution context for f
       
   226      * @param owner Owner object passed when clone is iterating an
       
   227      * object.  Used to set up context for cloned functions.
       
   228      * @return {Array|Object} the cloned object
       
   229      */
       
   230     Y.clone = function(o, safe, f, c, owner) {
       
   231 
       
   232         if (!L.isObject(o)) {
       
   233             return o;
       
   234         }
       
   235 
       
   236         var o2;
       
   237 
       
   238         switch (L.type(o)) {
       
   239             case 'date':
       
   240                 return new Date(o);
       
   241             case 'regexp':
       
   242                 return new RegExp(o.source);
       
   243             case 'function':
       
   244                 o2 = Y.bind(o, owner);
       
   245                 break;
       
   246             case 'array':
       
   247                 o2 = [];
       
   248                 break;
       
   249             default:
       
   250                 o2 = (safe) ? {} : Y.Object(o);
       
   251         }
       
   252 
       
   253         Y.each(o, function(v, k) {
       
   254             if (!f || (f.call(c || this, v, k, this, o) !== false)) {
       
   255                 this[k] =  Y.clone(v, safe, f, c, this);
       
   256             }
       
   257         }, o2);
       
   258 
       
   259         return o2;
       
   260     };
       
   261 
       
   262 
       
   263     /**
       
   264      * Returns a function that will execute the supplied function in the
       
   265      * supplied object's context, optionally adding any additional
       
   266      * supplied parameters to the beginning of the arguments collection the 
       
   267      * supplied to the function.
       
   268      *
       
   269      * @method bind
       
   270      * @param f {Function|String} the function to bind, or a function name
       
   271      * to execute on the context object
       
   272      * @param c the execution context
       
   273      * @param args* 0..n arguments to include before the arguments the 
       
   274      * function is executed with.
       
   275      * @return {function} the wrapped function
       
   276      */
       
   277     Y.bind = function(f, c) {
       
   278         var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
       
   279         return function () {
       
   280             var fn = L.isString(f) ? c[f] : f, 
       
   281                 args = (xargs) ? xargs.concat(Y.Array(arguments, 0, true)) : arguments;
       
   282             return fn.apply(c || fn, args);
       
   283         };
       
   284     };
       
   285     
       
   286     /**
       
   287      * Returns a function that will execute the supplied function in the
       
   288      * supplied object's context, optionally adding any additional
       
   289      * supplied parameters to the end of the arguments the function
       
   290      * is executed with.
       
   291      *
       
   292      * @method rbind
       
   293      * @param f {Function|String} the function to bind, or a function name
       
   294      * to execute on the context object
       
   295      * @param c the execution context
       
   296      * @param args* 0..n arguments to append to the end of arguments collection
       
   297      * supplied to the function
       
   298      * @return {function} the wrapped function
       
   299      */
       
   300     Y.rbind = function(f, c) {
       
   301         var xargs = arguments.length > 2 ? Y.Array(arguments, 2, true) : null;
       
   302         return function () {
       
   303             var fn = L.isString(f) ? c[f] : f, 
       
   304                 args = (xargs) ? Y.Array(arguments, 0, true).concat(xargs) : arguments;
       
   305             return fn.apply(c || fn, args);
       
   306         };
       
   307     };
       
   308 
       
   309 
       
   310 
       
   311 }, '3.0.0b1' );