BaseBuild.js revision 793e508bd277c48d6a09b91bb99064b4046eda7a
10139N/A /**
10139N/A * The base-build submodule provides Base.build functionality, which
10139N/A * can be used to create custom classes, by aggregating extensions onto
10139N/A * a main class.
10139N/A *
10139N/A * @module base
10139N/A * @submodule base-build
10139N/A * @for Base
10139N/A */
10139N/A
10139N/A var Base = Y.Base,
10139N/A L = Y.Lang;
10139N/A
10139N/A /**
10139N/A * The build configuration for the Base class.
10139N/A *
10139N/A * Defines the static fields which need to be aggregated
10139N/A * when the Base class is used as the main class passed to
10139N/A * the <a href="#method_Base.build">Base.build</a> method.
10139N/A *
10139N/A * @property Base._buildCfg
10139N/A * @type Object
10139N/A * @static
10139N/A * @final
10139N/A * @private
10139N/A */
10139N/A Base._buildCfg = {
10139N/A aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
10139N/A };
10139N/A
10139N/A /**
10139N/A * <p>
10139N/A * Builds a custom constructor function (class) from the
10139N/A * main function, and array of extension functions (classes)
10139N/A * provided. The NAME field for the constructor function is
10139N/A * defined by the first argument passed in.
10139N/A * </p>
10139N/A * <p>
10139N/A * The cfg object literal supports the following properties
10139N/A * </p>
10139N/A * <dl>
10139N/A * <dt>dynamic &#60;boolean&#62;</dt>
10139N/A * <dd>
10139N/A * <p>If true (default), a completely new class
10139N/A * is created which extends the main class, and acts as the
10139N/A * host on which the extension classes are augmented.</p>
10139N/A * <p>If false, the extensions classes are augmented directly to
10139N/A * the main class, modifying the main class' prototype.</p>
10139N/A * </dd>
10139N/A * <dt>aggregates &#60;String[]&#62;</dt>
10139N/A * <dd>An array of static property names, which will get aggregated
10139N/A * on to the built class, in addition to the default properties build
10139N/A * will always aggregate as defined by the main class' static _buildCfg
10139N/A * property.
10139N/A * </dd>
10139N/A * </dl>
10139N/A *
10139N/A * @method Base.build
10139N/A * @static
10139N/A * @param {Function} main The name of the new class. Used to defined the NAME property for the new class.
10139N/A * @param {Function} main The main class on which to base the built class
10139N/A * @param {Function[]} extensions The set of extension classes which will be
10139N/A * augmented/aggregated to the built class.
10139N/A * @param {Object} cfg Optional. Build configuration for the class (see description).
10139N/A * @return {Function} A custom class, created from the provided main and extension classes
10139N/A */
10139N/A Base.build = function(name, main, extensions, cfg) {
10139N/A
10139N/A var build = Base.build,
10139N/A builtClass = build._getClass(main, cfg),
10139N/A aggregates = build._getAggregates(main, cfg),
10139N/A dynamic = builtClass._yuibuild.dynamic,
10139N/A i, l, val, extClass;
10139N/A
10139N/A // Shallow isolate aggregates
10139N/A if (dynamic) {
10139N/A if (aggregates) {
10139N/A for (i = 0, l = aggregates.length; i < l; ++i) {
10139N/A val = aggregates[i];
10139N/A if (main.hasOwnProperty(val)) {
10139N/A builtClass[val] = L.isArray(main[val]) ? [] : {};
10139N/A }
10139N/A }
10139N/A Y.aggregate(builtClass, main, true, aggregates);
10139N/A }
10139N/A }
10139N/A
10139N/A // Augment/Aggregate
10139N/A for (i = 0, l = extensions.length; i < l; i++) {
10139N/A extClass = extensions[i];
10139N/A
10139N/A if (aggregates) {
10139N/A Y.aggregate(builtClass, extClass, true, aggregates);
10139N/A }
10139N/A
10139N/A // Old augment
10139N/A Y.mix(builtClass, extClass, true, null, 1);
10139N/A
10139N/A builtClass._yuibuild.exts.push(extClass);
10139N/A }
10139N/A
10139N/A builtClass.prototype.hasImpl = build._hasImpl;
10139N/A
10139N/A if (dynamic) {
10139N/A builtClass.NAME = name;
10139N/A builtClass.prototype.constructor = builtClass;
10139N/A }
10139N/A
10139N/A return builtClass;
10139N/A };
10139N/A
10139N/A Y.mix(Base.build, {
10139N/A
10139N/A _template: function(main) {
10139N/A
10139N/A function BuiltClass() {
10139N/A
10139N/A BuiltClass.superclass.constructor.apply(this, arguments);
10139N/A
10139N/A var f = BuiltClass._yuibuild.exts,
10139N/A l = f.length,
10139N/A i;
10139N/A
10139N/A for (i = 0; i < l; i++) {
10139N/A f[i].apply(this, arguments);
10139N/A }
10139N/A
10139N/A return this;
10139N/A }
10139N/A Y.extend(BuiltClass, main);
10139N/A
10139N/A return BuiltClass;
10139N/A },
10139N/A
10139N/A _hasImpl : function(extClass) {
10139N/A if (this.constructor._yuibuild) {
10139N/A var f = this.constructor._yuibuild.exts,
10139N/A l = f.length,
10139N/A i;
10139N/A
10139N/A for (i = 0; i < l; i++) {
10139N/A if (f[i] === extClass) {
10139N/A return true;
10139N/A }
10139N/A }
10139N/A }
10139N/A return false;
10139N/A },
10139N/A
10139N/A _getClass : function(main, cfg) {
10139N/A
10139N/A var dynamic = (cfg && false === cfg.dynamic) ? false : true,
10139N/A builtClass = (dynamic) ? Base.build._template(main) : main;
10139N/A
10139N/A builtClass._yuibuild = {
10139N/A id: null,
10139N/A exts : [],
10139N/A dynamic : dynamic
10139N/A };
10139N/A
10139N/A return builtClass;
10139N/A },
10139N/A
10139N/A _getAggregates : function(main, cfg) {
10139N/A var aggr = [],
10139N/A cfgAggr = (cfg && cfg.aggregates),
10139N/A c = main,
10139N/A classAggr;
10139N/A
10139N/A while (c && c.prototype) {
10139N/A classAggr = c._buildCfg && c._buildCfg.aggregates;
10139N/A if (classAggr) {
10139N/A aggr = aggr.concat(classAggr);
10139N/A }
10139N/A c = c.superclass ? c.superclass.constructor : null;
10139N/A }
10139N/A
10139N/A if (cfgAggr) {
10139N/A aggr = aggr.concat(cfgAggr);
10139N/A }
10139N/A
10139N/A return aggr;
10139N/A }
10139N/A });
10139N/A