]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/base/base-build.js
Release 6.2.0beta4
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / base / base-build.js
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-build', function(Y) {
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
20     var Base = Y.Base,
21         L = Y.Lang;
22
23     /**
24      * The build configuration for the Base class.
25      *
26      * Defines the static fields which need to be aggregated
27      * when the Base class is used as the main class passed to 
28      * the <a href="#method_Base.build">Base.build</a> method.
29      *
30      * @property Base._buildCfg
31      * @type Object
32      * @static
33      * @final
34      * @private
35      */
36     Base._buildCfg = {
37         aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
38     };
39
40     /**
41      * <p>
42      * Builds a custom constructor function (class) from the
43      * main function, and array of extension functions (classes)
44      * provided. The NAME field for the constructor function is 
45      * defined by the first argument passed in.
46      * </p>
47      * <p>
48      * The cfg object supports the following properties
49      * </p>
50      * <dl>
51      *    <dt>dynamic &#60;boolean&#62;</dt>
52      *    <dd>
53      *    <p>If true (default), a completely new class
54      *    is created which extends the main class, and acts as the 
55      *    host on which the extension classes are augmented.</p>
56      *    <p>If false, the extensions classes are augmented directly to
57      *    the main class, modifying the main class' prototype.</p>
58      *    </dd>
59      *    <dt>aggregates &#60;String[]&#62;</dt>
60      *    <dd>An array of static property names, which will get aggregated
61      *    on to the built class, in addition to the default properties build 
62      *    will always aggregate as defined by the main class' static _buildCfg
63      *    property.
64      *    </dd>
65      * </dl>
66      *
67      * @method Base.build
68      * @static
69      * @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
70      * @param {Function} main The main class on which to base the built class
71      * @param {Function[]} extensions The set of extension classes which will be
72      * augmented/aggregated to the built class.
73      * @param {Object} cfg Optional. Build configuration for the class (see description).
74      * @return {Function} A custom class, created from the provided main and extension classes
75      */
76     Base.build = function(name, main, extensions, cfg) {
77
78         var build = Base.build,
79             builtClass = build._getClass(main, cfg),
80             aggregates = build._getAggregates(main, cfg),
81             dynamic = builtClass._yuibuild.dynamic,
82             i, l, val, extClass;
83
84         // Shallow isolate aggregates
85         if (dynamic) {
86             if (aggregates) {
87                 for (i = 0, l = aggregates.length; i < l; ++i) {
88                     val = aggregates[i];
89                     if (main.hasOwnProperty(val)) {
90                         builtClass[val] = L.isArray(main[val]) ? [] : {};
91                     }
92                 }
93                 Y.aggregate(builtClass, main, true, aggregates);
94             }
95         }
96
97         // Augment/Aggregate
98         for (i = 0, l = extensions.length; i < l; i++) {
99             extClass = extensions[i];
100
101             if (aggregates) {
102                 Y.aggregate(builtClass, extClass, true, aggregates);
103             }
104
105             // Old augment
106             Y.mix(builtClass, extClass, true, null, 1);
107
108             builtClass._yuibuild.exts.push(extClass);
109         }
110
111         builtClass.prototype.hasImpl = build._hasImpl;
112
113         if (dynamic) {
114             builtClass.NAME = name;
115             builtClass.prototype.constructor = builtClass;
116         }
117
118         return builtClass;
119     };
120
121     Y.mix(Base.build, {
122
123         _template: function(main) {
124
125             function BuiltClass() {
126
127                 BuiltClass.superclass.constructor.apply(this, arguments);
128
129                 var f = BuiltClass._yuibuild.exts, 
130                     l = f.length,
131                     i;
132
133                 for (i = 0; i < l; i++) {
134                     f[i].apply(this, arguments);
135                 }
136
137                 return this;
138             }
139             Y.extend(BuiltClass, main);
140
141             return BuiltClass;
142         },
143
144         _hasImpl : function(extClass) {
145             var classes = this._getClasses();
146             for (var i = 0, l = classes.length; i < l; i++) {
147                 var cls = classes[i];
148                  
149                 if (cls._yuibuild) {
150                     var exts = cls._yuibuild.exts,
151                         ll = exts.length,
152                         j;
153     
154                     for (j = 0; j < ll; j++) {
155                         if (exts[j] === extClass) {
156                             return true;
157                         }
158                     }
159                 }
160             }
161             return false;
162         },
163
164         _getClass : function(main, cfg) {
165
166            var dynamic = (cfg && false === cfg.dynamic) ? false : true,
167                 builtClass = (dynamic) ? Base.build._template(main) : main;
168
169             builtClass._yuibuild = {
170                 id: null,
171                 exts : [],
172                 dynamic : dynamic
173             };
174
175             return builtClass;
176         },
177
178         _getAggregates : function(main, cfg) {
179             var aggr = [],
180                 cfgAggr = (cfg && cfg.aggregates),
181                 c = main,
182                 classAggr;
183
184             while (c && c.prototype) {
185                 classAggr = c._buildCfg && c._buildCfg.aggregates;
186                 if (classAggr) {
187                     aggr = aggr.concat(classAggr);
188                 }
189                 c = c.superclass ? c.superclass.constructor : null;
190             }
191
192             if (cfgAggr) {
193                 aggr = aggr.concat(cfgAggr);
194             }
195
196             return aggr;
197         }
198     });
199
200
201 }, '3.0.0' ,{requires:['base-base']});