Dashboard sipadu mbip
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

base-build.js 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('base-build', function(Y) {
  9. /**
  10. * The base-build submodule provides Base.build functionality, which
  11. * can be used to create custom classes, by aggregating extensions onto
  12. * a main class.
  13. *
  14. * @module base
  15. * @submodule base-build
  16. * @for Base
  17. */
  18. var Base = Y.Base,
  19. L = Y.Lang,
  20. INITIALIZER = "initializer",
  21. DESTRUCTOR = "destructor",
  22. build;
  23. Base._build = function(name, main, extensions, px, sx, cfg) {
  24. var build = Base._build,
  25. builtClass = build._ctor(main, cfg),
  26. buildCfg = build._cfg(main, cfg),
  27. _mixCust = build._mixCust,
  28. aggregates = buildCfg.aggregates,
  29. custom = buildCfg.custom,
  30. dynamic = builtClass._yuibuild.dynamic,
  31. i, l, val, extClass, extProto,
  32. initializer,
  33. destructor;
  34. if (dynamic && aggregates) {
  35. for (i = 0, l = aggregates.length; i < l; ++i) {
  36. val = aggregates[i];
  37. if (main.hasOwnProperty(val)) {
  38. builtClass[val] = L.isArray(main[val]) ? [] : {};
  39. }
  40. }
  41. }
  42. // Augment/Aggregate
  43. for (i = 0, l = extensions.length; i < l; i++) {
  44. extClass = extensions[i];
  45. extProto = extClass.prototype;
  46. initializer = extProto[INITIALIZER];
  47. destructor = extProto[DESTRUCTOR];
  48. delete extProto[INITIALIZER];
  49. delete extProto[DESTRUCTOR];
  50. // Prototype, old non-displacing augment
  51. Y.mix(builtClass, extClass, true, null, 1);
  52. // Custom Statics
  53. _mixCust(builtClass, extClass, aggregates, custom);
  54. if (initializer) {
  55. extProto[INITIALIZER] = initializer;
  56. }
  57. if (destructor) {
  58. extProto[DESTRUCTOR] = destructor;
  59. }
  60. builtClass._yuibuild.exts.push(extClass);
  61. }
  62. if (px) {
  63. Y.mix(builtClass.prototype, px, true);
  64. }
  65. if (sx) {
  66. Y.mix(builtClass, build._clean(sx, aggregates, custom), true);
  67. _mixCust(builtClass, sx, aggregates, custom);
  68. }
  69. builtClass.prototype.hasImpl = build._impl;
  70. if (dynamic) {
  71. builtClass.NAME = name;
  72. builtClass.prototype.constructor = builtClass;
  73. }
  74. return builtClass;
  75. };
  76. build = Base._build;
  77. Y.mix(build, {
  78. _mixCust: function(r, s, aggregates, custom) {
  79. if (aggregates) {
  80. Y.aggregate(r, s, true, aggregates);
  81. }
  82. if (custom) {
  83. for (var j in custom) {
  84. if (custom.hasOwnProperty(j)) {
  85. custom[j](j, r, s);
  86. }
  87. }
  88. }
  89. },
  90. _tmpl: function(main) {
  91. function BuiltClass() {
  92. BuiltClass.superclass.constructor.apply(this, arguments);
  93. }
  94. Y.extend(BuiltClass, main);
  95. return BuiltClass;
  96. },
  97. _impl : function(extClass) {
  98. var classes = this._getClasses(), i, l, cls, exts, ll, j;
  99. for (i = 0, l = classes.length; i < l; i++) {
  100. cls = classes[i];
  101. if (cls._yuibuild) {
  102. exts = cls._yuibuild.exts;
  103. ll = exts.length;
  104. for (j = 0; j < ll; j++) {
  105. if (exts[j] === extClass) {
  106. return true;
  107. }
  108. }
  109. }
  110. }
  111. return false;
  112. },
  113. _ctor : function(main, cfg) {
  114. var dynamic = (cfg && false === cfg.dynamic) ? false : true,
  115. builtClass = (dynamic) ? build._tmpl(main) : main,
  116. buildCfg = builtClass._yuibuild;
  117. if (!buildCfg) {
  118. buildCfg = builtClass._yuibuild = {};
  119. }
  120. buildCfg.id = buildCfg.id || null;
  121. buildCfg.exts = buildCfg.exts || [];
  122. buildCfg.dynamic = dynamic;
  123. return builtClass;
  124. },
  125. _cfg : function(main, cfg) {
  126. var aggr = [],
  127. cust = {},
  128. buildCfg,
  129. cfgAggr = (cfg && cfg.aggregates),
  130. cfgCustBuild = (cfg && cfg.custom),
  131. c = main;
  132. while (c && c.prototype) {
  133. buildCfg = c._buildCfg;
  134. if (buildCfg) {
  135. if (buildCfg.aggregates) {
  136. aggr = aggr.concat(buildCfg.aggregates);
  137. }
  138. if (buildCfg.custom) {
  139. Y.mix(cust, buildCfg.custom, true);
  140. }
  141. }
  142. c = c.superclass ? c.superclass.constructor : null;
  143. }
  144. if (cfgAggr) {
  145. aggr = aggr.concat(cfgAggr);
  146. }
  147. if (cfgCustBuild) {
  148. Y.mix(cust, cfg.cfgBuild, true);
  149. }
  150. return {
  151. aggregates: aggr,
  152. custom: cust
  153. };
  154. },
  155. _clean : function(sx, aggregates, custom) {
  156. var prop, i, l, sxclone = Y.merge(sx);
  157. for (prop in custom) {
  158. if (sxclone.hasOwnProperty(prop)) {
  159. delete sxclone[prop];
  160. }
  161. }
  162. for (i = 0, l = aggregates.length; i < l; i++) {
  163. prop = aggregates[i];
  164. if (sxclone.hasOwnProperty(prop)) {
  165. delete sxclone[prop];
  166. }
  167. }
  168. return sxclone;
  169. }
  170. });
  171. /**
  172. * <p>
  173. * Builds a custom constructor function (class) from the
  174. * main function, and array of extension functions (classes)
  175. * provided. The NAME field for the constructor function is
  176. * defined by the first argument passed in.
  177. * </p>
  178. * <p>
  179. * The cfg object supports the following properties
  180. * </p>
  181. * <dl>
  182. * <dt>dynamic &#60;boolean&#62;</dt>
  183. * <dd>
  184. * <p>If true (default), a completely new class
  185. * is created which extends the main class, and acts as the
  186. * host on which the extension classes are augmented.</p>
  187. * <p>If false, the extensions classes are augmented directly to
  188. * the main class, modifying the main class' prototype.</p>
  189. * </dd>
  190. * <dt>aggregates &#60;String[]&#62;</dt>
  191. * <dd>An array of static property names, which will get aggregated
  192. * on to the built class, in addition to the default properties build
  193. * will always aggregate as defined by the main class' static _buildCfg
  194. * property.
  195. * </dd>
  196. * </dl>
  197. *
  198. * @method build
  199. * @deprecated Use the more convenient Base.create and Base.mix methods instead
  200. * @static
  201. * @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
  202. * @param {Function} main The main class on which to base the built class
  203. * @param {Function[]} extensions The set of extension classes which will be
  204. * augmented/aggregated to the built class.
  205. * @param {Object} cfg Optional. Build configuration for the class (see description).
  206. * @return {Function} A custom class, created from the provided main and extension classes
  207. */
  208. Base.build = function(name, main, extensions, cfg) {
  209. return build(name, main, extensions, null, null, cfg);
  210. };
  211. /**
  212. * <p>Creates a new class (constructor function) which extends the base class passed in as the second argument,
  213. * and mixes in the array of extensions provided.</p>
  214. * <p>Prototype properties or methods can be added to the new class, using the px argument (similar to Y.extend).</p>
  215. * <p>Static properties or methods can be added to the new class, using the sx argument (similar to Y.extend).</p>
  216. * <p>
  217. *
  218. * </p>
  219. * @method create
  220. * @static
  221. * @param {Function} name The name of the newly created class. Used to defined the NAME property for the new class.
  222. * @param {Function} main The base class which the new class should extend. This class needs to be Base or a class derived from base (e.g. Widget).
  223. * @param {Function[]} extensions The list of extensions which will be mixed into the built class.
  224. * @param {Object} px The set of prototype properties/methods to add to the built class.
  225. * @param {Object} sx The set of static properties/methods to add to the built class.
  226. * @return {Function} The newly created class.
  227. */
  228. Base.create = function(name, base, extensions, px, sx) {
  229. return build(name, base, extensions, px, sx);
  230. };
  231. /**
  232. * <p>Mixes in a list of extensions to an existing class.</p>
  233. * @method mix
  234. * @static
  235. * @param {Function} main The existing class into which the extensions should be mixed. The class needs to be Base or a class derived from Base (e.g. Widget)
  236. * @param {Function[]} extensions The set of extension classes which will mixed into the existing main class.
  237. * @return {Function} The modified main class, with extensions mixed in.
  238. */
  239. Base.mix = function(main, extensions) {
  240. return build(null, main, extensions, null, null, {dynamic:false});
  241. };
  242. /**
  243. * The build configuration for the Base class.
  244. *
  245. * Defines the static fields which need to be aggregated
  246. * when the Base class is used as the main class passed to
  247. * the <a href="#method_Base.build">Base.build</a> method.
  248. *
  249. * @property _buildCfg
  250. * @type Object
  251. * @static
  252. * @final
  253. * @private
  254. */
  255. Base._buildCfg = {
  256. custom : {
  257. ATTRS : function(prop, r, s) {
  258. r.ATTRS = r.ATTRS || {};
  259. if (s.ATTRS) {
  260. var sAttrs = s.ATTRS,
  261. rAttrs = r.ATTRS,
  262. a;
  263. for (a in sAttrs) {
  264. if (sAttrs.hasOwnProperty(a)) {
  265. rAttrs[a] = rAttrs[a] || {};
  266. Y.mix(rAttrs[a], sAttrs[a], true);
  267. }
  268. }
  269. }
  270. }
  271. },
  272. aggregates : ["_PLUG", "_UNPLUG"]
  273. };
  274. }, '3.4.0' ,{requires:['base-base']});