src/cm/media/js/lib/yui/yui3.0.0/build/base/base-base-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.0
       
     6 build: 1549
       
     7 */
       
     8 YUI.add('base-base', function(Y) {
       
     9 
       
    10     /**
       
    11      * The base module provides the Base class, which objects requiring attribute and custom event support can extend. 
       
    12      * The module also provides two ways to reuse code - An augmentable Plugin.Host interface which provides plugin support 
       
    13      * (which is augmented to the Base class) and Base.build which provides a way to 
       
    14      * build custom classes using extensions.
       
    15      *
       
    16      * @module base
       
    17      */
       
    18 
       
    19     /**
       
    20      * The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host, 
       
    21      * and without the extension support provided by Base.build.
       
    22      *
       
    23      * @module base
       
    24      * @submodule base-base
       
    25      */
       
    26     var O = Y.Object,
       
    27         L = Y.Lang,
       
    28         DOT = ".",
       
    29         DESTROY = "destroy",
       
    30         INIT = "init",
       
    31         INITIALIZED = "initialized",
       
    32         DESTROYED = "destroyed",
       
    33         INITIALIZER = "initializer",
       
    34         OBJECT_CONSTRUCTOR = Object.prototype.constructor,
       
    35         DEEP = "deep",
       
    36         SHALLOW = "shallow",
       
    37         DESTRUCTOR = "destructor",
       
    38 
       
    39         Attribute = Y.Attribute;
       
    40 
       
    41     /**
       
    42      * <p>
       
    43      * A base class which objects requiring attributes and custom event support can 
       
    44      * extend. Base also handles the chaining of initializer and destructor methods across 
       
    45      * the hierarchy as part of object construction and destruction. Additionally, attributes configured 
       
    46      * through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class 
       
    47      * in the hierarchy will be initialized by Base.
       
    48      * </p>
       
    49      *
       
    50      * <p>
       
    51      * The static <a href="#property_Base.NAME">NAME</a> property of each class extending 
       
    52      * from Base will be used as the identifier for the class, and is used by Base to prefix 
       
    53      * all events fired by instances of that class.
       
    54      * </p>
       
    55      * @class Base
       
    56      * @constructor
       
    57      * @uses Attribute
       
    58      * @uses Plugin.Host
       
    59      *
       
    60      * @param {Object} config Object with configuration property name/value pairs
       
    61      */
       
    62     function Base() {
       
    63         Y.log('constructor called', 'life', 'base');
       
    64 
       
    65         Attribute.call(this);
       
    66 
       
    67         // If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
       
    68         // initial state, but don't initialize Plugins yet. That's done after initialization.
       
    69         var PluginHost = Y.Plugin && Y.Plugin.Host;  
       
    70         if (this._initPlugins && PluginHost) {
       
    71             PluginHost.call(this);
       
    72         }
       
    73 
       
    74         if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
       
    75 
       
    76         this.init.apply(this, arguments);
       
    77     }
       
    78 
       
    79     /**
       
    80      * The list of properties which can be configured for 
       
    81      * each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
       
    82      *
       
    83      * @property Base._ATTR_CFG
       
    84      * @type Array
       
    85      * @static
       
    86      * @private
       
    87      */
       
    88     Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
       
    89 
       
    90     /**
       
    91      * <p>
       
    92      * The string to be used to identify instances of 
       
    93      * this class, for example in prefixing events.
       
    94      * </p>
       
    95      * <p>
       
    96      * Classes extending Base, should define their own
       
    97      * static NAME property, which should be camelCase by
       
    98      * convention (e.g. MyClass.NAME = "myClass";).
       
    99      * </p>
       
   100      * @property Base.NAME
       
   101      * @type String
       
   102      * @static
       
   103      */
       
   104     Base.NAME = "base";
       
   105 
       
   106     /**
       
   107      * The default set of attributes which will be available for instances of this class, and 
       
   108      * their configuration. In addition to the configuration properties listed by 
       
   109      * Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute 
       
   110      * can also be configured with a "cloneDefaultValue" property, which defines how the statically
       
   111      * defined value field should be protected ("shallow", "deep" and false are supported values). 
       
   112      *
       
   113      * By default if the value is an object literal or an array it will be "shallow" cloned, to 
       
   114      * protect the default value.
       
   115      *
       
   116      * @property Base.ATTRS
       
   117      * @type Object
       
   118      * @static
       
   119      */
       
   120     Base.ATTRS = {
       
   121         /**
       
   122          * Flag indicating whether or not this object
       
   123          * has been through the init lifecycle phase.
       
   124          *
       
   125          * @attribute initialized
       
   126          * @readonly
       
   127          * @default false
       
   128          * @type boolean
       
   129          */
       
   130         initialized: {
       
   131             readOnly:true,
       
   132             value:false
       
   133         },
       
   134 
       
   135         /**
       
   136          * Flag indicating whether or not this object
       
   137          * has been through the destroy lifecycle phase.
       
   138          *
       
   139          * @attribute destroyed
       
   140          * @readonly
       
   141          * @default false
       
   142          * @type boolean
       
   143          */
       
   144         destroyed: {
       
   145             readOnly:true,
       
   146             value:false
       
   147         }
       
   148     };
       
   149 
       
   150     Base.prototype = {
       
   151 
       
   152         /**
       
   153          * Init lifecycle method, invoked during construction.
       
   154          * Fires the init event prior to setting up attributes and 
       
   155          * invoking initializers for the class hierarchy.
       
   156          *
       
   157          * @method init
       
   158          * @final
       
   159          * @chainable
       
   160          * @param {Object} config Object with configuration property name/value pairs
       
   161          * @return {Base} A reference to this object
       
   162          */
       
   163         init: function(config) {
       
   164             Y.log('init called', 'life', 'base');
       
   165 
       
   166             /**
       
   167              * The string used to identify the class of this object.
       
   168              *
       
   169              * @deprecated Use this.constructor.NAME
       
   170              * @property name
       
   171              * @type String
       
   172              */
       
   173             this._yuievt.config.prefix = this.name = this.constructor.NAME;
       
   174 
       
   175             /**
       
   176              * <p>
       
   177              * Lifecycle event for the init phase, fired prior to initialization. 
       
   178              * Invoking the preventDefault() method on the event object provided 
       
   179              * to subscribers will prevent initialization from occuring.
       
   180              * </p>
       
   181              * <p>
       
   182              * Subscribers to the "after" momemt of this event, will be notified
       
   183              * after initialization of the object is complete (and therefore
       
   184              * cannot prevent initialization).
       
   185              * </p>
       
   186              *
       
   187              * @event init
       
   188              * @preventable _defInitFn
       
   189              * @param {EventFacade} e Event object, with a cfg property which 
       
   190              * refers to the configuration object passed to the constructor.
       
   191              */
       
   192             this.publish(INIT, {
       
   193                 queuable:false,
       
   194                 defaultFn:this._defInitFn
       
   195             });
       
   196 
       
   197             if (config) {
       
   198                 if (config.on) {
       
   199                     this.on(config.on);
       
   200                 }
       
   201                 if (config.after) {
       
   202                     this.after(config.after);
       
   203                 }
       
   204             }
       
   205 
       
   206             this.fire(INIT, {cfg: config});
       
   207 
       
   208             return this;
       
   209         },
       
   210 
       
   211         /**
       
   212          * <p>
       
   213          * Destroy lifecycle method. Fires the destroy
       
   214          * event, prior to invoking destructors for the
       
   215          * class hierarchy.
       
   216          * </p>
       
   217          * <p>
       
   218          * Subscribers to the destroy
       
   219          * event can invoke preventDefault on the event object, to prevent destruction
       
   220          * from proceeding.
       
   221          * </p>
       
   222          * @method destroy
       
   223          * @return {Base} A reference to this object
       
   224          * @final
       
   225          * @chainable
       
   226          */
       
   227         destroy: function() {
       
   228             Y.log('destroy called', 'life', 'base');
       
   229 
       
   230             /**
       
   231              * <p>
       
   232              * Lifecycle event for the destroy phase, 
       
   233              * fired prior to destruction. Invoking the preventDefault 
       
   234              * method on the event object provided to subscribers will 
       
   235              * prevent destruction from proceeding.
       
   236              * </p>
       
   237              * <p>
       
   238              * Subscribers to the "after" moment of this event, will be notified
       
   239              * after destruction is complete (and as a result cannot prevent
       
   240              * destruction).
       
   241              * </p>
       
   242              * @event destroy
       
   243              * @preventable _defDestroyFn
       
   244              * @param {EventFacade} e Event object
       
   245              */
       
   246             this.publish(DESTROY, {
       
   247                 queuable:false,
       
   248                 defaultFn: this._defDestroyFn
       
   249             });
       
   250             this.fire(DESTROY);
       
   251             return this;
       
   252         },
       
   253 
       
   254         /**
       
   255          * Default init event handler
       
   256          *
       
   257          * @method _defInitFn
       
   258          * @param {EventFacade} e Event object, with a cfg property which 
       
   259          * refers to the configuration object passed to the constructor.
       
   260          * @protected
       
   261          */
       
   262         _defInitFn : function(e) {
       
   263             this._initHierarchy(e.cfg);
       
   264             if (this._initPlugins) {
       
   265                 // Need to initPlugins manually, to handle constructor parsing, static Plug parsing
       
   266                 this._initPlugins(e.cfg);
       
   267             }
       
   268             this._set(INITIALIZED, true);
       
   269         },
       
   270 
       
   271         /**
       
   272          * Default destroy event handler
       
   273          *
       
   274          * @method _defDestroyFn
       
   275          * @param {EventFacade} e Event object
       
   276          * @protected
       
   277          */
       
   278         _defDestroyFn : function(e) {
       
   279             this._destroyHierarchy();
       
   280             if (this._destroyPlugins) {
       
   281                 this._destroyPlugins();
       
   282             }
       
   283             this._set(DESTROYED, true);
       
   284         },
       
   285 
       
   286         /**
       
   287          * Returns the class hierarchy for this object, with Base being the last class in the array.
       
   288          *
       
   289          * @method _getClasses
       
   290          * @protected
       
   291          * @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
       
   292          * This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the 
       
   293          * cached value.
       
   294          */
       
   295         _getClasses : function() {
       
   296             if (!this._classes) {
       
   297                 this._initHierarchyData();
       
   298             }
       
   299             return this._classes;
       
   300         },
       
   301 
       
   302         /**
       
   303          * Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
       
   304          *
       
   305          * @method _getAttrCfgs
       
   306          * @protected
       
   307          * @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
       
   308          * This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
       
   309          * the cached value.
       
   310          */
       
   311         _getAttrCfgs : function() {
       
   312             if (!this._attrs) {
       
   313                 this._initHierarchyData();
       
   314             }
       
   315             return this._attrs;
       
   316         },
       
   317 
       
   318         /**
       
   319          * A helper method used when processing ATTRS across the class hierarchy during 
       
   320          * initialization. Returns a disposable object with the attributes defined for 
       
   321          * the provided class, extracted from the set of all attributes passed in .
       
   322          *
       
   323          * @method _filterAttrCfs
       
   324          * @private
       
   325          *
       
   326          * @param {Function} clazz The class for which the desired attributes are required.
       
   327          * @param {Object} allCfgs The set of all attribute configurations for this instance. 
       
   328          * Attributes will be removed from this set, if they belong to the filtered class, so
       
   329          * that by the time all classes are processed, allCfgs will be empty.
       
   330          * 
       
   331          * @return {Object} The set of attributes belonging to the class passed in, in the form
       
   332          * of an object with attribute name/configuration pairs.
       
   333          */
       
   334         _filterAttrCfgs : function(clazz, allCfgs) {
       
   335             var cfgs = null, attr, attrs = clazz.ATTRS;
       
   336 
       
   337             if (attrs) {
       
   338                 for (attr in attrs) {
       
   339                     if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
       
   340                         cfgs = cfgs || {};
       
   341                         cfgs[attr] = allCfgs[attr];
       
   342                         delete allCfgs[attr];
       
   343                     }
       
   344                 }
       
   345             }
       
   346 
       
   347             return cfgs;
       
   348         },
       
   349 
       
   350         /**
       
   351          * A helper method used by _getClasses and _getAttrCfgs, which determines both
       
   352          * the array of classes and aggregate set of attribute configurations
       
   353          * across the class hierarchy for the instance.
       
   354          * 
       
   355          * @method _initHierarchyData
       
   356          * @private
       
   357          */
       
   358         _initHierarchyData : function() {
       
   359             var c = this.constructor, 
       
   360                 classes = [],
       
   361                 attrs = [];
       
   362 
       
   363             while (c) {
       
   364                 // Add to classes
       
   365                 classes[classes.length] = c;
       
   366 
       
   367                 // Add to attributes
       
   368                 if (c.ATTRS) {
       
   369                     attrs[attrs.length] = c.ATTRS;
       
   370                 }
       
   371                 c = c.superclass ? c.superclass.constructor : null;
       
   372             }
       
   373 
       
   374             this._classes = classes;
       
   375             this._attrs = this._aggregateAttrs(attrs);
       
   376         },
       
   377 
       
   378         /**
       
   379          * A helper method, used by _initHierarchyData to aggregate 
       
   380          * attribute configuration across the instances class hierarchy.
       
   381          *
       
   382          * The method will potect the attribute configuration value to protect the statically defined 
       
   383          * default value in ATTRS if required (if the value is an object literal, array or the 
       
   384          * attribute configuration has cloneDefaultValue set to shallow or deep).
       
   385          *
       
   386          * @method _aggregateAttrs
       
   387          * @private
       
   388          * @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy 
       
   389          * (subclass first, Base last)
       
   390          * @return {Object} The aggregate set of ATTRS definitions for the instance
       
   391          */
       
   392         _aggregateAttrs : function(allAttrs) {
       
   393             var attr,
       
   394                 attrs,
       
   395                 cfg,
       
   396                 val,
       
   397                 path,
       
   398                 i, 
       
   399                 clone, 
       
   400                 cfgProps = Base._ATTR_CFG,
       
   401                 aggAttrs = {};
       
   402 
       
   403             if (allAttrs) {
       
   404                 for (i = allAttrs.length-1; i >= 0; --i) {
       
   405                     attrs = allAttrs[i];
       
   406 
       
   407                     for (attr in attrs) {
       
   408                         if (attrs.hasOwnProperty(attr)) {
       
   409 
       
   410                             // Protect config passed in
       
   411                             cfg = Y.mix({}, attrs[attr], true, cfgProps);
       
   412 
       
   413                             val = cfg.value;
       
   414                             clone = cfg.cloneDefaultValue;
       
   415 
       
   416                             if (val) {
       
   417                                 if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
       
   418                                     Y.log('Cloning default value for attribute:' + attr, 'info', 'base');
       
   419                                     cfg.value = Y.clone(val);
       
   420                                 } else if (clone === SHALLOW) {
       
   421                                     Y.log('Merging default value for attribute:' + attr, 'info', 'base');
       
   422                                     cfg.value = Y.merge(val);
       
   423                                 }
       
   424                                 // else if (clone === false), don't clone the static default value. 
       
   425                                 // It's intended to be used by reference.
       
   426                             }
       
   427 
       
   428                             path = null;
       
   429                             if (attr.indexOf(DOT) !== -1) {
       
   430                                 path = attr.split(DOT);
       
   431                                 attr = path.shift();
       
   432                             }
       
   433 
       
   434                             if (path && aggAttrs[attr] && aggAttrs[attr].value) {
       
   435                                 O.setValue(aggAttrs[attr].value, path, val);
       
   436                             } else if (!path){
       
   437                                 if (!aggAttrs[attr]) {
       
   438                                     aggAttrs[attr] = cfg;
       
   439                                 } else {
       
   440                                     Y.mix(aggAttrs[attr], cfg, true, cfgProps);
       
   441                                 }
       
   442                             }
       
   443                         }
       
   444                     }
       
   445                 }
       
   446             }
       
   447 
       
   448             return aggAttrs;
       
   449         },
       
   450 
       
   451         /**
       
   452          * Initializes the class hierarchy for the instance, which includes 
       
   453          * initializing attributes for each class defined in the class's 
       
   454          * static <a href="#property_Base.ATTRS">ATTRS</a> property and 
       
   455          * invoking the initializer method on the prototype of each class in the hierarchy.
       
   456          *
       
   457          * @method _initHierarchy
       
   458          * @param {Object} userVals Object with configuration property name/value pairs
       
   459          * @private
       
   460          */
       
   461         _initHierarchy : function(userVals) {
       
   462             var lazy = this._lazyAddAttrs,
       
   463                 constr,
       
   464                 constrProto,
       
   465                 ci,
       
   466                 ei,
       
   467                 el,
       
   468                 classes = this._getClasses(),
       
   469                 attrCfgs = this._getAttrCfgs();
       
   470 
       
   471             for (ci = classes.length-1; ci >= 0; ci--) {
       
   472 
       
   473                 constr = classes[ci];
       
   474                 constrProto = constr.prototype;
       
   475 
       
   476                 if (constr._yuibuild && constr._yuibuild.exts && !constr._yuibuild.dynamic) {
       
   477                     for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
       
   478                         constr._yuibuild.exts[ei].apply(this, arguments);
       
   479                     }
       
   480                 }
       
   481 
       
   482                 this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
       
   483 
       
   484                 if (constrProto.hasOwnProperty(INITIALIZER)) {
       
   485                     constrProto.initializer.apply(this, arguments);
       
   486                 }
       
   487             }
       
   488         },
       
   489 
       
   490         /**
       
   491          * Destroys the class hierarchy for this instance by invoking
       
   492          * the descructor method on the prototype of each class in the hierarchy.
       
   493          *
       
   494          * @method _destroyHierarchy
       
   495          * @private
       
   496          */
       
   497         _destroyHierarchy : function() {
       
   498             var constr,
       
   499                 constrProto,
       
   500                 ci, cl,
       
   501                 classes = this._getClasses();
       
   502 
       
   503             for (ci = 0, cl = classes.length; ci < cl; ci++) {
       
   504                 constr = classes[ci];
       
   505                 constrProto = constr.prototype;
       
   506                 if (constrProto.hasOwnProperty(DESTRUCTOR)) {
       
   507                     constrProto.destructor.apply(this, arguments);
       
   508                 }
       
   509             }
       
   510         },
       
   511 
       
   512         /**
       
   513          * Default toString implementation. Provides the constructor NAME
       
   514          * and the instance ID.
       
   515          *
       
   516          * @method toString
       
   517          * @return {String} String representation for this object
       
   518          */
       
   519         toString: function() {
       
   520             return this.constructor.NAME + "[" + Y.stamp(this) + "]";
       
   521         }
       
   522     };
       
   523 
       
   524     // Straightup augment, no wrapper functions
       
   525     Y.mix(Base, Attribute, false, null, 1);
       
   526 
       
   527     // Fix constructor
       
   528     Base.prototype.constructor = Base;
       
   529 
       
   530     Y.Base = Base;
       
   531 
       
   532     // Fix constructor
       
   533     Base.prototype.constructor = Base;
       
   534 
       
   535 
       
   536 }, '3.0.0' ,{requires:['attribute-base']});