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