Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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