Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. AUI.add('aui-component', function(A) {
  2. /**
  3. * The Component Utility
  4. *
  5. * @module aui-component
  6. */
  7. var Lang = A.Lang,
  8. AArray = A.Array,
  9. concat = function(arr, arr2) {
  10. return (arr || []).concat(arr2 || []);
  11. },
  12. ClassNameManager = A.ClassNameManager,
  13. _getClassName = ClassNameManager.getClassName,
  14. _getWidgetClassName = A.Widget.getClassName,
  15. getClassName = A.getClassName,
  16. NAME = 'component',
  17. CSS_HELPER_HIDDEN = getClassName('helper', 'hidden'),
  18. CONSTRUCTOR_OBJECT = A.config.win.Object.prototype.constructor,
  19. STR_BLANK = ' ';
  20. /**
  21. * A base class for Component, providing:
  22. * <ul>
  23. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  24. * <li></li>
  25. * </ul>
  26. *
  27. * Check the list of <a href="Component.html#configattributes">Configuration Attributes</a> available for
  28. * Component.
  29. *
  30. * @param config {Object} Object literal specifying widget configuration properties.
  31. *
  32. * @class Component
  33. * @constructor
  34. * @extends Widget
  35. */
  36. var Component = function(config) {
  37. var instance = this;
  38. instance._originalConfig = config;
  39. instance._setRender(config);
  40. Component.superclass.constructor.apply(this, arguments);
  41. INSTANCES[instance.get('id')] = instance;
  42. };
  43. var INSTANCES = Component._INSTANCES = {};
  44. /**
  45. * Static property provides a string to identify the class.
  46. *
  47. * @property Component.NAME
  48. * @type String
  49. * @static
  50. */
  51. Component.NAME = 'component';
  52. /**
  53. * Static property used to define the default attribute
  54. * configuration for the Component.
  55. *
  56. * @property Component.ATTRS
  57. * @type Object
  58. * @static
  59. */
  60. Component.ATTRS = {
  61. /**
  62. * Boolean indicating if use of the WAI-ARIA Roles and States should be
  63. * enabled for the Widget.
  64. *
  65. * @attribute useARIA
  66. * @readOnly
  67. * @writeOnce
  68. * @default true
  69. * @type boolean
  70. */
  71. useARIA: {
  72. writeOnce: true,
  73. value: false,
  74. validator: Lang.isBoolean
  75. },
  76. /**
  77. * CSS class to be automatically added to the <code>boundingBox</code>.
  78. *
  79. * @attribute cssClass
  80. * @default null
  81. * @type String
  82. */
  83. cssClass: {
  84. lazyAdd: false,
  85. value: null
  86. },
  87. /**
  88. * css class added to hide the <code>boundingBox</code> when
  89. * <a href="Component.html#config_visible">visible</a> is set to
  90. * <code>false</code>.
  91. *
  92. * @attribute hideClass
  93. * @default 'aui-helper-hidden'
  94. * @type String
  95. */
  96. hideClass: {
  97. value: CSS_HELPER_HIDDEN
  98. },
  99. /**
  100. * If <code>true</code> the render phase will be autimatically invoked
  101. * preventing the <code>.render()</code> manual call.
  102. *
  103. * @attribute render
  104. * @default false
  105. * @type boolean | Node
  106. */
  107. render: {
  108. value: false,
  109. writeOnce: true
  110. }
  111. };
  112. A.extend(
  113. Component,
  114. A.Widget,
  115. {
  116. /**
  117. * Construction logic executed during Component instantiation. Lifecycle.
  118. *
  119. * @method initializer
  120. * @protected
  121. */
  122. initializer: function(config) {
  123. var instance = this;
  124. if (config && config.cssClass) {
  125. instance._uiSetCssClass(config.cssClass);
  126. }
  127. instance.after('cssClassChange', instance._afterCssClassChange);
  128. },
  129. /**
  130. * Clone the current Component.
  131. *
  132. * @method clone
  133. * @param {Object} config
  134. * @return {Widget} Cloned instance.
  135. */
  136. clone: function(config) {
  137. var instance = this;
  138. config = config || {};
  139. config.id = config.id || A.guid();
  140. A.mix(config, instance._originalConfig);
  141. return new instance.constructor(config);
  142. },
  143. /**
  144. * Toggle the visibility of the Panel toggling the value of the
  145. * <a href="Widget.html#config_visible">visible</a> attribute.
  146. *
  147. * @method toggle
  148. * @param visible Force the visibility of the component to this state.
  149. */
  150. toggle: function(visible) {
  151. var instance = this;
  152. if (!Lang.isBoolean(visible)) {
  153. visible = !instance.get('visible');
  154. }
  155. return instance.set('visible', visible);
  156. },
  157. _uiSetVisible: function(value) {
  158. var instance = this;
  159. var superUISetVisible = Component.superclass._uiSetVisible;
  160. if (superUISetVisible) {
  161. superUISetVisible.apply(instance, arguments);
  162. }
  163. var hideClass = instance.get('hideClass');
  164. if (hideClass !== false) {
  165. var boundingBox = instance.get('boundingBox');
  166. boundingBox.toggleClass(hideClass || CSS_HELPER_HIDDEN, !value);
  167. }
  168. },
  169. /**
  170. * Fires after the value of the
  171. * <a href="Component.html#config_cssClass">cssClass</a> attribute change.
  172. *
  173. * @method _afterCssClassChange
  174. * @param {EventFacade} event
  175. * @protected
  176. */
  177. _afterCssClassChange: function(event) {
  178. var instance = this;
  179. instance._uiSetCssClass(event.newVal, event.prevVal);
  180. },
  181. /**
  182. * Applies standard class names to the boundingBox and contentBox
  183. *
  184. * @method _renderBoxClassNames
  185. * @protected
  186. */
  187. _renderBoxClassNames : function() {
  188. var instance = this;
  189. var boundingBoxNode = instance.get('boundingBox')._node;
  190. var contentBoxNode = instance.get('contentBox')._node;
  191. var boundingBoxNodeClassName = boundingBoxNode.className;
  192. var contentBoxNodeClassName = contentBoxNode.className;
  193. var boundingBoxBuffer = (boundingBoxNodeClassName) ? boundingBoxNodeClassName.split(STR_BLANK) : [];
  194. var contentBoxBuffer = (contentBoxNodeClassName) ? contentBoxNodeClassName.split(STR_BLANK) : [];
  195. var classes = instance._getClasses();
  196. var classLength = classes.length;
  197. var auiClassesLength = classLength - 4;
  198. var classItem;
  199. var classItemName;
  200. boundingBoxBuffer.push(_getWidgetClassName());
  201. for (var i = classLength - 3; i >= 0; i--) {
  202. classItem = classes[i];
  203. classItemName = String(classItem.NAME).toLowerCase();
  204. boundingBoxBuffer.push(classItem.CSS_PREFIX || _getClassName(classItemName));
  205. if (i <= auiClassesLength) {
  206. classItemName = classItemName;
  207. contentBoxBuffer.push(getClassName(classItemName, 'content'));
  208. }
  209. }
  210. contentBoxBuffer.push(instance.getClassName('content'));
  211. if (boundingBoxNode === contentBoxNode) {
  212. contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer.concat(boundingBoxBuffer)).join(STR_BLANK);
  213. }
  214. else {
  215. boundingBoxNode.className = AArray.dedupe(boundingBoxBuffer).join(STR_BLANK);
  216. contentBoxNodeClassName = AArray.dedupe(contentBoxBuffer).join(STR_BLANK);
  217. }
  218. contentBoxNode.className = contentBoxNodeClassName;
  219. },
  220. /**
  221. * Renders the Component based upon a passed in interaction.
  222. *
  223. * @method _renderInteraction
  224. * @protected
  225. */
  226. _renderInteraction: function(event, parentNode) {
  227. var instance = this;
  228. instance.render(parentNode);
  229. var renderHandles = instance._renderHandles;
  230. for (var i = renderHandles.length - 1; i >= 0; i--) {
  231. var handle = renderHandles.pop();
  232. handle.detach();
  233. }
  234. },
  235. /**
  236. * Set the interaction and render behavior based upon an object
  237. * (intercepts the default rendering behavior).
  238. *
  239. * @method _setRender
  240. * @protected
  241. */
  242. _setRender: function(config) {
  243. var instance = this;
  244. var render = config && config.render;
  245. if (render && render.constructor == CONSTRUCTOR_OBJECT) {
  246. var eventType = render.eventType || 'mousemove';
  247. var parentNode = render.parentNode;
  248. var selector = render.selector || parentNode;
  249. if (selector) {
  250. instance._renderHandles = [];
  251. var renderHandles = instance._renderHandles;
  252. if (!Lang.isArray(eventType)) {
  253. eventType = [eventType];
  254. }
  255. var renderInteraction = A.rbind(instance._renderInteraction, instance, parentNode);
  256. var interactionNode = A.one(selector);
  257. for (var i = eventType.length - 1; i >= 0; i--) {
  258. renderHandles[i] = interactionNode.once(eventType[i], renderInteraction);
  259. }
  260. delete config.render;
  261. }
  262. }
  263. },
  264. /**
  265. * Applies the CSS classes to the <code>boundingBox</code> and
  266. * <code>contentBox</code>.
  267. *
  268. * @method _uiSetCssClass
  269. * @protected
  270. * @param {String} newVal
  271. * @param {String} prevVal
  272. */
  273. _uiSetCssClass: function(newVal, prevVal) {
  274. var instance = this;
  275. var prevValContent = prevVal + '-content';
  276. var newValContent = newVal + '-content';
  277. var boundingBox = instance.get('boundingBox');
  278. var contentBox = instance.get('contentBox');
  279. boundingBox.replaceClass(prevVal, newVal);
  280. contentBox.replaceClass(prevValContent, newValContent);
  281. }
  282. }
  283. );
  284. Component.getById = function(id) {
  285. return INSTANCES[id];
  286. };
  287. var COMP_PROTO = Component.prototype;
  288. var DEFAULT_UI_ATTRS = A.Widget.prototype._UI_ATTRS;
  289. Component._applyCssPrefix = function(component) {
  290. if (component && component.NAME && !('CSS_PREFIX' in component)) {
  291. component.CSS_PREFIX = A.getClassName(String(component.NAME).toLowerCase());
  292. }
  293. return component;
  294. };
  295. Component.create = function(config) {
  296. config = config || {};
  297. var extendsClass = config.EXTENDS || A.Component;
  298. var component = config.constructor;
  299. if (!A.Object.owns(config, 'constructor')){
  300. component = function(){
  301. component.superclass.constructor.apply(this, arguments);
  302. };
  303. }
  304. var configProto = config.prototype;
  305. if (configProto) {
  306. if (config.UI_ATTRS || config.BIND_UI_ATTRS || config.SYNC_UI_ATTRS) {
  307. var BIND_UI_ATTRS = concat(config.BIND_UI_ATTRS, config.UI_ATTRS);
  308. var SYNC_UI_ATTRS = concat(config.SYNC_UI_ATTRS, config.UI_ATTRS);
  309. var extendsProto = extendsClass.prototype;
  310. var extendsUIAttrs = (extendsProto && extendsProto._UI_ATTRS) || DEFAULT_UI_ATTRS;
  311. BIND_UI_ATTRS = concat(extendsUIAttrs.BIND, BIND_UI_ATTRS);
  312. SYNC_UI_ATTRS = concat(extendsUIAttrs.SYNC, SYNC_UI_ATTRS);
  313. var configProtoUIAttrs = configProto._UI_ATTRS;
  314. if (!configProtoUIAttrs) {
  315. configProtoUIAttrs = configProto._UI_ATTRS = {};
  316. }
  317. if (BIND_UI_ATTRS.length) {
  318. configProtoUIAttrs.BIND = BIND_UI_ATTRS;
  319. }
  320. if (SYNC_UI_ATTRS.length) {
  321. configProtoUIAttrs.SYNC = SYNC_UI_ATTRS;
  322. }
  323. }
  324. }
  325. var augmentsClasses = config.AUGMENTS;
  326. if (augmentsClasses && !Lang.isArray(augmentsClasses)) {
  327. augmentsClasses = [augmentsClasses];
  328. }
  329. A.mix(component, config);
  330. delete component.prototype;
  331. A.extend(component, extendsClass, configProto);
  332. if (augmentsClasses) {
  333. component = A.Base.build(config.NAME, component, augmentsClasses, { dynamic: false });
  334. }
  335. Component._applyCssPrefix(component);
  336. return component;
  337. };
  338. Component.CSS_PREFIX = getClassName('component');
  339. var Base = A.Base;
  340. Component.build = function() {
  341. var component = Base.build.apply(Base, arguments);
  342. Component._applyCssPrefix(component);
  343. return component;
  344. };
  345. A.Component = Component;
  346. }, '@VERSION@' ,{skinnable:false, requires:['aui-classnamemanager','base-build','widget']});