src/cm/media/js/lib/yui/yui3-3.15.0/build/base-build/base-build-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('base-build', function (Y, NAME) {
       
     2 
       
     3     /**
       
     4      * The base-build submodule provides Base.build functionality, which
       
     5      * can be used to create custom classes, by aggregating extensions onto
       
     6      * a main class.
       
     7      *
       
     8      * @module base
       
     9      * @submodule base-build
       
    10      * @for Base
       
    11      */
       
    12     var BaseCore = Y.BaseCore,
       
    13         Base     = Y.Base,
       
    14         L        = Y.Lang,
       
    15 
       
    16         INITIALIZER = "initializer",
       
    17         DESTRUCTOR  = "destructor",
       
    18         AGGREGATES  = ["_PLUG", "_UNPLUG"],
       
    19 
       
    20         build;
       
    21 
       
    22     // Utility function used in `_buildCfg` to aggregate array values into a new
       
    23     // array from the sender constructor to the receiver constructor.
       
    24     function arrayAggregator(prop, r, s) {
       
    25         if (s[prop]) {
       
    26             r[prop] = (r[prop] || []).concat(s[prop]);
       
    27         }
       
    28     }
       
    29 
       
    30     // Utility function used in `_buildCfg` to aggregate `_ATTR_CFG` array
       
    31     // values from the sender constructor into a new array on receiver's
       
    32     // constructor, and clear the cached hash.
       
    33     function attrCfgAggregator(prop, r, s) {
       
    34         if (s._ATTR_CFG) {
       
    35             // Clear cached hash.
       
    36             r._ATTR_CFG_HASH = null;
       
    37 
       
    38             arrayAggregator.apply(null, arguments);
       
    39         }
       
    40     }
       
    41 
       
    42     // Utility function used in `_buildCfg` to aggregate ATTRS configs from one
       
    43     // the sender constructor to the receiver constructor.
       
    44     function attrsAggregator(prop, r, s) {
       
    45         BaseCore.modifyAttrs(r, s.ATTRS);
       
    46     }
       
    47 
       
    48     Base._build = function(name, main, extensions, px, sx, cfg) {
       
    49 
       
    50         var build = Base._build,
       
    51 
       
    52             builtClass = build._ctor(main, cfg),
       
    53             buildCfg = build._cfg(main, cfg, extensions),
       
    54 
       
    55             _mixCust = build._mixCust,
       
    56 
       
    57             dynamic = builtClass._yuibuild.dynamic,
       
    58 
       
    59             i, l, extClass, extProto,
       
    60             initializer,
       
    61             destructor;
       
    62 
       
    63         // Augment/Aggregate
       
    64         for (i = 0, l = extensions.length; i < l; i++) {
       
    65             extClass = extensions[i];
       
    66 
       
    67             extProto = extClass.prototype;
       
    68 
       
    69             initializer = extProto[INITIALIZER];
       
    70             destructor = extProto[DESTRUCTOR];
       
    71             delete extProto[INITIALIZER];
       
    72             delete extProto[DESTRUCTOR];
       
    73 
       
    74             // Prototype, old non-displacing augment
       
    75             Y.mix(builtClass, extClass, true, null, 1);
       
    76 
       
    77             // Custom Statics
       
    78             _mixCust(builtClass, extClass, buildCfg);
       
    79 
       
    80             if (initializer) {
       
    81                 extProto[INITIALIZER] = initializer;
       
    82             }
       
    83 
       
    84             if (destructor) {
       
    85                 extProto[DESTRUCTOR] = destructor;
       
    86             }
       
    87 
       
    88             builtClass._yuibuild.exts.push(extClass);
       
    89         }
       
    90 
       
    91         if (px) {
       
    92             Y.mix(builtClass.prototype, px, true);
       
    93         }
       
    94 
       
    95         if (sx) {
       
    96             Y.mix(builtClass, build._clean(sx, buildCfg), true);
       
    97             _mixCust(builtClass, sx, buildCfg);
       
    98         }
       
    99 
       
   100         builtClass.prototype.hasImpl = build._impl;
       
   101 
       
   102         if (dynamic) {
       
   103             builtClass.NAME = name;
       
   104             builtClass.prototype.constructor = builtClass;
       
   105 
       
   106             // Carry along the reference to `modifyAttrs()` from `main`.
       
   107             builtClass.modifyAttrs = main.modifyAttrs;
       
   108         }
       
   109 
       
   110         return builtClass;
       
   111     };
       
   112 
       
   113     build = Base._build;
       
   114 
       
   115     Y.mix(build, {
       
   116 
       
   117         _mixCust: function(r, s, cfg) {
       
   118 
       
   119             var aggregates,
       
   120                 custom,
       
   121                 statics,
       
   122                 aggr,
       
   123                 l,
       
   124                 i;
       
   125 
       
   126             if (cfg) {
       
   127                 aggregates = cfg.aggregates;
       
   128                 custom = cfg.custom;
       
   129                 statics = cfg.statics;
       
   130             }
       
   131 
       
   132             if (statics) {
       
   133                 Y.mix(r, s, true, statics);
       
   134             }
       
   135 
       
   136             if (aggregates) {
       
   137                 for (i = 0, l = aggregates.length; i < l; i++) {
       
   138                     aggr = aggregates[i];
       
   139                     if (!r.hasOwnProperty(aggr) && s.hasOwnProperty(aggr)) {
       
   140                         r[aggr] = L.isArray(s[aggr]) ? [] : {};
       
   141                     }
       
   142                     Y.aggregate(r, s, true, [aggr]);
       
   143                 }
       
   144             }
       
   145 
       
   146             if (custom) {
       
   147                 for (i in custom) {
       
   148                     if (custom.hasOwnProperty(i)) {
       
   149                         custom[i](i, r, s);
       
   150                     }
       
   151                 }
       
   152             }
       
   153 
       
   154         },
       
   155 
       
   156         _tmpl: function(main) {
       
   157 
       
   158             function BuiltClass() {
       
   159                 BuiltClass.superclass.constructor.apply(this, arguments);
       
   160             }
       
   161             Y.extend(BuiltClass, main);
       
   162 
       
   163             return BuiltClass;
       
   164         },
       
   165 
       
   166         _impl : function(extClass) {
       
   167             var classes = this._getClasses(), i, l, cls, exts, ll, j;
       
   168             for (i = 0, l = classes.length; i < l; i++) {
       
   169                 cls = classes[i];
       
   170                 if (cls._yuibuild) {
       
   171                     exts = cls._yuibuild.exts;
       
   172                     ll = exts.length;
       
   173 
       
   174                     for (j = 0; j < ll; j++) {
       
   175                         if (exts[j] === extClass) {
       
   176                             return true;
       
   177                         }
       
   178                     }
       
   179                 }
       
   180             }
       
   181             return false;
       
   182         },
       
   183 
       
   184         _ctor : function(main, cfg) {
       
   185 
       
   186            var dynamic = (cfg && false === cfg.dynamic) ? false : true,
       
   187                builtClass = (dynamic) ? build._tmpl(main) : main,
       
   188                buildCfg = builtClass._yuibuild;
       
   189 
       
   190             if (!buildCfg) {
       
   191                 buildCfg = builtClass._yuibuild = {};
       
   192             }
       
   193 
       
   194             buildCfg.id = buildCfg.id || null;
       
   195             buildCfg.exts = buildCfg.exts || [];
       
   196             buildCfg.dynamic = dynamic;
       
   197 
       
   198             return builtClass;
       
   199         },
       
   200 
       
   201         _cfg : function(main, cfg, exts) {
       
   202             var aggr = [],
       
   203                 cust = {},
       
   204                 statics = [],
       
   205                 buildCfg,
       
   206                 cfgAggr = (cfg && cfg.aggregates),
       
   207                 cfgCustBuild = (cfg && cfg.custom),
       
   208                 cfgStatics = (cfg && cfg.statics),
       
   209                 c = main,
       
   210                 i,
       
   211                 l;
       
   212 
       
   213             // Prototype Chain
       
   214             while (c && c.prototype) {
       
   215                 buildCfg = c._buildCfg;
       
   216                 if (buildCfg) {
       
   217                     if (buildCfg.aggregates) {
       
   218                         aggr = aggr.concat(buildCfg.aggregates);
       
   219                     }
       
   220                     if (buildCfg.custom) {
       
   221                         Y.mix(cust, buildCfg.custom, true);
       
   222                     }
       
   223                     if (buildCfg.statics) {
       
   224                         statics = statics.concat(buildCfg.statics);
       
   225                     }
       
   226                 }
       
   227                 c = c.superclass ? c.superclass.constructor : null;
       
   228             }
       
   229 
       
   230             // Exts
       
   231             if (exts) {
       
   232                 for (i = 0, l = exts.length; i < l; i++) {
       
   233                     c = exts[i];
       
   234                     buildCfg = c._buildCfg;
       
   235                     if (buildCfg) {
       
   236                         if (buildCfg.aggregates) {
       
   237                             aggr = aggr.concat(buildCfg.aggregates);
       
   238                         }
       
   239                         if (buildCfg.custom) {
       
   240                             Y.mix(cust, buildCfg.custom, true);
       
   241                         }
       
   242                         if (buildCfg.statics) {
       
   243                             statics = statics.concat(buildCfg.statics);
       
   244                         }
       
   245                     }
       
   246                 }
       
   247             }
       
   248 
       
   249             if (cfgAggr) {
       
   250                 aggr = aggr.concat(cfgAggr);
       
   251             }
       
   252 
       
   253             if (cfgCustBuild) {
       
   254                 Y.mix(cust, cfg.cfgBuild, true);
       
   255             }
       
   256 
       
   257             if (cfgStatics) {
       
   258                 statics = statics.concat(cfgStatics);
       
   259             }
       
   260 
       
   261             return {
       
   262                 aggregates: aggr,
       
   263                 custom: cust,
       
   264                 statics: statics
       
   265             };
       
   266         },
       
   267 
       
   268         _clean : function(sx, cfg) {
       
   269             var prop, i, l, sxclone = Y.merge(sx),
       
   270                 aggregates = cfg.aggregates,
       
   271                 custom = cfg.custom;
       
   272 
       
   273             for (prop in custom) {
       
   274                 if (sxclone.hasOwnProperty(prop)) {
       
   275                     delete sxclone[prop];
       
   276                 }
       
   277             }
       
   278 
       
   279             for (i = 0, l = aggregates.length; i < l; i++) {
       
   280                 prop = aggregates[i];
       
   281                 if (sxclone.hasOwnProperty(prop)) {
       
   282                     delete sxclone[prop];
       
   283                 }
       
   284             }
       
   285 
       
   286             return sxclone;
       
   287         }
       
   288     });
       
   289 
       
   290     /**
       
   291      * <p>
       
   292      * Builds a custom constructor function (class) from the
       
   293      * main function, and array of extension functions (classes)
       
   294      * provided. The NAME field for the constructor function is
       
   295      * defined by the first argument passed in.
       
   296      * </p>
       
   297      * <p>
       
   298      * The cfg object supports the following properties
       
   299      * </p>
       
   300      * <dl>
       
   301      *    <dt>dynamic &#60;boolean&#62;</dt>
       
   302      *    <dd>
       
   303      *    <p>If true (default), a completely new class
       
   304      *    is created which extends the main class, and acts as the
       
   305      *    host on which the extension classes are augmented.</p>
       
   306      *    <p>If false, the extensions classes are augmented directly to
       
   307      *    the main class, modifying the main class' prototype.</p>
       
   308      *    </dd>
       
   309      *    <dt>aggregates &#60;String[]&#62;</dt>
       
   310      *    <dd>An array of static property names, which will get aggregated
       
   311      *    on to the built class, in addition to the default properties build
       
   312      *    will always aggregate as defined by the main class' static _buildCfg
       
   313      *    property.
       
   314      *    </dd>
       
   315      * </dl>
       
   316      *
       
   317      * @method build
       
   318      * @deprecated Use the more convenient Base.create and Base.mix methods instead
       
   319      * @static
       
   320      * @param {Function} name The name of the new class. Used to define the NAME property for the new class.
       
   321      * @param {Function} main The main class on which to base the built class
       
   322      * @param {Function[]} extensions The set of extension classes which will be
       
   323      * augmented/aggregated to the built class.
       
   324      * @param {Object} cfg Optional. Build configuration for the class (see description).
       
   325      * @return {Function} A custom class, created from the provided main and extension classes
       
   326      */
       
   327     Base.build = function(name, main, extensions, cfg) {
       
   328         return build(name, main, extensions, null, null, cfg);
       
   329     };
       
   330 
       
   331     /**
       
   332      * Creates a new class (constructor function) which extends the base class passed in as the second argument,
       
   333      * and mixes in the array of extensions provided.
       
   334      *
       
   335      * Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).
       
   336      *
       
   337      * Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).
       
   338      *
       
   339      * **NOTE FOR COMPONENT DEVELOPERS**: Both the `base` class, and `extensions` can define static a `_buildCfg`
       
   340      * property, which acts as class creation meta-data, and drives how special static properties from the base
       
   341      * class, or extensions should be copied, aggregated or (custom) mixed into the newly created class.
       
   342      *
       
   343      * The `_buildCfg` property is a hash with 3 supported properties: `statics`, `aggregates` and `custom`, e.g:
       
   344      *
       
   345      *     // If the Base/Main class is the thing introducing the property:
       
   346      *
       
   347      *     MyBaseClass._buildCfg = {
       
   348      *
       
   349      *        // Static properties/methods to copy (Alias) to the built class.
       
   350      *        statics: ["CopyThisMethod", "CopyThisProperty"],
       
   351      *
       
   352      *        // Static props to aggregate onto the built class.
       
   353      *        aggregates: ["AggregateThisProperty"],
       
   354      *
       
   355      *        // Static properties which need custom handling (e.g. deep merge etc.)
       
   356      *        custom: {
       
   357      *           "CustomProperty" : function(property, Receiver, Supplier) {
       
   358      *              ...
       
   359      *              var triggers = Receiver.CustomProperty.triggers;
       
   360      *              Receiver.CustomProperty.triggers = triggers.concat(Supplier.CustomProperty.triggers);
       
   361      *              ...
       
   362      *           }
       
   363      *        }
       
   364      *     };
       
   365      *
       
   366      *     MyBaseClass.CopyThisMethod = function() {...};
       
   367      *     MyBaseClass.CopyThisProperty = "foo";
       
   368      *     MyBaseClass.AggregateThisProperty = {...};
       
   369      *     MyBaseClass.CustomProperty = {
       
   370      *        triggers: [...]
       
   371      *     }
       
   372      *
       
   373      *     // Or, if the Extension is the thing introducing the property:
       
   374      *
       
   375      *     MyExtension._buildCfg = {
       
   376      *         statics : ...
       
   377      *         aggregates : ...
       
   378      *         custom : ...
       
   379      *     }
       
   380      *
       
   381      * This way, when users pass your base or extension class to `Y.Base.create` or `Y.Base.mix`, they don't need to
       
   382      * know which properties need special handling. `Y.Base` has a buildCfg which defines `ATTRS` for custom mix handling
       
   383      * (to protect the static config objects), and `Y.Widget` has a buildCfg which specifies `HTML_PARSER` for
       
   384      * straight up aggregation.
       
   385      *
       
   386      * @method create
       
   387      * @static
       
   388      * @param {String} name The name of the newly created class. Used to define the NAME property for the new class.
       
   389      * @param {Function} main The base class which the new class should extend.
       
   390      * This class needs to be Base or a class derived from base (e.g. Widget).
       
   391      * @param {Function[]} extensions The list of extensions which will be mixed into the built class.
       
   392      * @param {Object} px The set of prototype properties/methods to add to the built class.
       
   393      * @param {Object} sx The set of static properties/methods to add to the built class.
       
   394      * @return {Function} The newly created class.
       
   395      */
       
   396     Base.create = function(name, base, extensions, px, sx) {
       
   397         return build(name, base, extensions, px, sx);
       
   398     };
       
   399 
       
   400     /**
       
   401      * <p>Mixes in a list of extensions to an existing class.</p>
       
   402      * @method mix
       
   403      * @static
       
   404      * @param {Function} main The existing class into which the extensions should be mixed.
       
   405      * The class needs to be Base or a class derived from Base (e.g. Widget)
       
   406      * @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
       
   407      * @return {Function} The modified main class, with extensions mixed in.
       
   408      */
       
   409     Base.mix = function(main, extensions) {
       
   410 
       
   411         if (main._CACHED_CLASS_DATA) {
       
   412             main._CACHED_CLASS_DATA = null;
       
   413         }
       
   414 
       
   415         return build(null, main, extensions, null, null, {dynamic:false});
       
   416     };
       
   417 
       
   418     /**
       
   419      * The build configuration for the Base class.
       
   420      *
       
   421      * Defines the static fields which need to be aggregated when the Base class
       
   422      * is used as the main class passed to the
       
   423      * <a href="#method_Base.build">Base.build</a> method.
       
   424      *
       
   425      * @property _buildCfg
       
   426      * @type Object
       
   427      * @static
       
   428      * @final
       
   429      * @private
       
   430      */
       
   431     BaseCore._buildCfg = {
       
   432         aggregates: AGGREGATES.concat(),
       
   433 
       
   434         custom: {
       
   435             ATTRS         : attrsAggregator,
       
   436             _ATTR_CFG     : attrCfgAggregator,
       
   437             _NON_ATTRS_CFG: arrayAggregator
       
   438         }
       
   439     };
       
   440 
       
   441     // Makes sure Base and BaseCore use separate `_buildCfg` objects.
       
   442     Base._buildCfg = {
       
   443         aggregates: AGGREGATES.concat(),
       
   444 
       
   445         custom: {
       
   446             ATTRS         : attrsAggregator,
       
   447             _ATTR_CFG     : attrCfgAggregator,
       
   448             _NON_ATTRS_CFG: arrayAggregator
       
   449         }
       
   450     };
       
   451 
       
   452 
       
   453 }, '@VERSION@', {"requires": ["base-base"]});