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