]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/widget/widget-child.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / widget / widget-child.js
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.3.0
6 build: 3167
7 */
8 YUI.add('widget-child', function(Y) {
9
10 /**
11  * Extension enabling a Widget to be a child of another Widget.
12  *
13  * @module widget-child
14  */
15
16 var Lang = Y.Lang;
17
18 /**
19  * Widget extension providing functionality enabling a Widget to be a 
20  * child of another Widget.
21  *
22  * @class WidgetChild
23  * @param {Object} config User configuration object.
24 */
25 function Child() {
26
27     //  Widget method overlap
28     Y.after(this._syncUIChild, this, "syncUI");
29     Y.after(this._bindUIChild, this, "bindUI");
30
31 }
32
33 Child.ATTRS = {
34
35     /**
36      * @attribute selected
37      * @type Number
38      * @default 0
39      *
40      * @description Number indicating if the Widget is selected.  Possible 
41      * values are:
42      * <dl>
43      * <dt>0</dt> <dd>(Default) Not selected</dd>
44      * <dt>1</dt> <dd>Fully selected</dd>
45      * <dt>2</dt> <dd>Partially selected</dd>
46      * </dl>
47     */
48     selected: {   
49         value: 0,
50         validator: Lang.isNumber
51     },
52
53
54     /**
55      * @attribute index
56      * @type Number
57      * @readOnly
58      *
59      * @description Number representing the Widget's ordinal position in its 
60      * parent Widget.
61      */
62     index: {
63         readOnly: true,
64         getter: function () {
65             
66             var parent = this.get("parent"),
67                 index = -1;
68             
69             if (parent) {
70                 index = parent.indexOf(this);
71             }
72             
73             return index;
74             
75         }
76     },
77
78
79     /**
80      * @attribute parent
81      * @type Widget
82      * @readOnly
83      *
84      * @description Retrieves the parent of the Widget in the object hierarchy.
85     */
86     parent: {
87         readOnly: true
88     },
89
90
91     /**
92      * @attribute depth
93      * @type Number
94      * @default -1 
95      * @readOnly         
96      *
97      * @description Number representing the depth of this Widget relative to 
98      * the root Widget in the object heirarchy.
99      */
100     depth: {
101         readOnly: true,
102         getter: function () {
103             
104             var parent = this.get("parent"),
105                 root = this.get("root"),
106                 depth = -1;
107             
108             while (parent) {
109
110                 depth = (depth + 1);
111
112                 if (parent == root) {
113                     break;
114                 }
115
116                 parent = parent.get("parent");
117
118             }
119             
120             return depth;
121             
122         }
123     },
124
125     /**
126      * @attribute root
127      * @type Widget 
128      * @readOnly         
129      *
130      * @description Returns the root Widget in the object hierarchy.  If the
131      * ROOT_TYPE property is set, the search for the root Widget will be 
132      * constrained to parent Widgets of the specified type.
133      */
134     root: {
135         readOnly: true,
136         getter: function () {
137
138             var getParent = function (child) {
139
140                 var parent = child.get("parent"),
141                     FnRootType = child.ROOT_TYPE,
142                     criteria = parent;
143
144                 if (FnRootType) {
145                     criteria = (parent && Y.instanceOf(parent, FnRootType));
146                 }
147
148                 return (criteria ? getParent(parent) : child);
149                 
150             };
151
152             return getParent(this);
153             
154         }
155     }
156
157 };
158
159 Child.prototype = {
160
161     /**
162      * Constructor reference used to determine the root of a Widget-based 
163      * object tree.
164      * <p>
165      * Currently used to control the behavior of the <code>root</code>  
166      * attribute so that recursing up the object heirarchy can be constrained 
167      * to a specific type of Widget.  Widget authors should set this property
168      * to the constructor function for a given Widget implementation.
169      * </p>
170      *
171      * @property ROOT_TYPE
172      * @type Object
173      */
174     ROOT_TYPE: null,
175
176
177     //  Override of Widget's implementation of _getUIEventNode() to ensure that 
178     //  all event listeners are bound to the Widget's topmost DOM element.
179     //  This ensures that the firing of each type of Widget UI event (click,
180     //  mousedown, etc.) is facilitated by a single, top-level, delegated DOM
181     //  event listener.
182     _getUIEventNode: function () {
183     
184         var root = this.get("root"),
185             returnVal;
186         
187         if (root) {
188             returnVal = root.get("boundingBox");
189         }
190     
191         return returnVal;
192         
193     },
194
195
196     /**
197     * @method next
198     * @description Returns the Widget's next sibling.
199     * @param {Boolean} circular Boolean indicating if the parent's first child 
200     * should be returned if the child has no next sibling.  
201     * @return {Widget} Widget instance. 
202     */
203     next: function (circular) {
204
205         var parent = this.get("parent"),
206             sibling;
207
208         if (parent) {
209             sibling = parent.item((this.get("index")+1));
210         }
211
212         if (!sibling && circular) {
213             sibling = parent.item(0);
214         }
215
216         return sibling;
217
218     },
219
220
221     /**
222     * @method previous
223     * @description Returns the Widget's previous sibling.
224     * @param {Boolean} circular Boolean indicating if the parent's last child 
225     * should be returned if the child has no previous sibling.
226     * @return {Widget} Widget instance. 
227     */
228     previous: function (circular) {
229
230         var parent = this.get("parent"),
231             index = this.get("index"),
232             sibling;
233         
234         if (parent && index > 0) {
235             sibling = parent.item([(index-1)]);
236         }
237
238         if (!sibling && circular) {
239             sibling = parent.item((parent.size() - 1));
240         }
241
242         return sibling; 
243         
244     },
245
246
247     //  Override of Y.WidgetParent.remove()
248     //  Sugar implementation allowing a child to remove itself from its parent.
249     remove: function (index) {
250
251         var parent,
252             removed;
253
254         if (Lang.isNumber(index)) {
255             removed = Y.WidgetParent.prototype.remove.apply(this, arguments);
256         }
257         else {
258
259             parent = this.get("parent");
260
261             if (parent) {
262                 removed = parent.remove(this.get("index"));
263             }
264                         
265         }
266         
267         return removed;
268         
269     },
270
271
272     /**
273     * @method isRoot
274     * @description Determines if the Widget is the root Widget in the 
275     * object hierarchy.
276     * @return {Boolean} Boolean indicating if Widget is the root Widget in the 
277     * object hierarchy.
278     */
279     isRoot: function () {
280         return (this == this.get("root"));
281     },
282
283
284     /**
285     * @method ancestor
286     * @description Returns the Widget instance at the specified depth.
287     * @param {number} depth Number representing the depth of the ancestor.
288     * @return {Widget} Widget instance.
289     */
290     ancestor: function (depth) {
291
292         var root = this.get("root"),
293             parent;
294
295         if (this.get("depth") > depth)  {
296
297             parent = this.get("parent");
298
299             while (parent != root && parent.get("depth") > depth) {
300                 parent = parent.get("parent");
301             }
302
303         }
304
305         return parent;
306
307     },
308
309
310     /**
311      * Updates the UI to reflect the <code>selected</code> attribute value.
312      *
313      * @method _uiSetChildSelected
314      * @protected
315      * @param {number} selected The selected value to be reflected in the UI.
316      */    
317     _uiSetChildSelected: function (selected) {
318
319         var box = this.get("boundingBox"),
320             sClassName = this.getClassName("selected");
321
322         if (selected === 0) {
323             box.removeClass(sClassName);
324         }
325         else {
326             box.addClass(sClassName);
327         }
328         
329     },
330
331
332     /**
333      * Default attribute change listener for the <code>selected</code> 
334      * attribute, responsible for updating the UI, in response to 
335      * attribute changes.
336      *
337      * @method _afterChildSelectedChange
338      * @protected
339      * @param {EventFacade} event The event facade for the attribute change.
340      */    
341     _afterChildSelectedChange: function (event) {
342         this._uiSetChildSelected(event.newVal);
343     },
344     
345
346     /**
347      * Synchronizes the UI to match the WidgetChild state.
348      * <p>
349      * This method is invoked after bindUI is invoked for the Widget class
350      * using YUI's aop infrastructure.
351      * </p>     
352      *
353      * @method _syncUIChild
354      * @protected
355      */    
356     _syncUIChild: function () {
357         this._uiSetChildSelected(this.get("selected"));
358     },
359
360
361     /**
362      * Binds event listeners responsible for updating the UI state in response 
363      * to WidgetChild related state changes.
364      * <p>
365      * This method is invoked after bindUI is invoked for the Widget class
366      * using YUI's aop infrastructure.
367      * </p>
368      * @method _bindUIChild
369      * @protected
370      */    
371     _bindUIChild: function () { 
372         this.after("selectedChange", this._afterChildSelectedChange);
373     }
374     
375 };
376
377 Y.WidgetChild = Child;
378
379
380 }, '3.3.0' ,{requires:['base-build', 'widget']});