MDL-32843 import YUI 3.5.1
[moodle.git] / lib / yui / 3.5.1 / build / widget-autohide / widget-autohide-debug.js
blob4530fbe5ac777722caba047229601ad7de9973e8
1 /*
2 YUI 3.5.1 (build 22)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('widget-autohide', function(Y) {
9 /**
10  * A widget-level extension that provides ability to hide widget when
11  * certain events occur.
12  *
13  * @module widget-autohide
14  * @author eferraiuolo, tilomitra
15  * @since 3.4.0
16  */
19 var WIDGET_AUTOHIDE    = 'widgetAutohide',
20     AUTOHIDE            = 'autohide',
21     CLICK_OUTSIDE     = 'clickoutside',
22     FOCUS_OUTSIDE     = 'focusoutside',
23     DOCUMENT            = 'document',
24     KEY                 = 'key',
25     PRESS_ESCAPE         = 'esc',
26     BIND_UI             = 'bindUI',
27     SYNC_UI             = "syncUI",
28     RENDERED            = "rendered",
29     BOUNDING_BOX        = "boundingBox",
30     VISIBLE             = "visible",
31     CHANGE              = 'Change',
33     getCN               = Y.ClassNameManager.getClassName;
35 /**
36  * The WidgetAutohide class provides the hideOn attribute which can
37  * be used to hide the widget when certain events occur.
38  *
39  * @class WidgetAutohide
40  * @param {Object} config User configuration object
41  */
42 function WidgetAutohide(config) {
43     Y.after(this._bindUIAutohide, this, BIND_UI);
44     Y.after(this._syncUIAutohide, this, SYNC_UI);
47     if (this.get(RENDERED)) {
48         this._bindUIAutohide();
49         this._syncUIAutohide();
50     }
54 /**
55 * Static property used to define the default attribute
56 * configuration introduced by WidgetAutohide.
58 * @property ATTRS
59 * @static
60 * @type Object
62 WidgetAutohide.ATTRS = {
65     /**
66      * @attribute hideOn
67      * @type array
68      *
69      * @description An array of objects corresponding to the nodes, events, and keycodes to hide the widget on.
70      * The implementer can supply an array of objects, with each object having the following properties:
71      * <p>eventName: (string, required): The eventName to listen to.</p>
72      * <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p>
73      * <p>keyCode: (string, optional): If listening for key events, specify the keyCode</p>
74      * <p>By default, this attribute consists of one object which will cause the widget to hide if the
75      * escape key is pressed.</p>
76      */
77     hideOn: {
78         validator: Y.Lang.isArray,
79         valueFn  : function() {
80             return [
81                 {
82                     node: Y.one(DOCUMENT),
83                     eventName: KEY,
84                     keyCode: PRESS_ESCAPE
85                 }
86             ];
87         }
88     }
91 WidgetAutohide.prototype = {
92     // *** Instance Members *** //
94         _uiHandlesAutohide : null,
96         // *** Lifecycle Methods *** //
98         destructor : function () {
100             this._detachUIHandlesAutohide();
101         },
103         /**
104          * Binds event listeners to the widget.
105          * <p>
106          * This method in invoked after bindUI is invoked for the Widget class
107          * using YUI's aop infrastructure.
108          * </p>
109          * @method _bindUIAutohide
110          * @protected
111          */
112         _bindUIAutohide : function () {
114             this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeAutohide);
115             this.after("hideOnChange", this._afterHideOnChange);
116         },
118         /**
119          * Syncs up the widget based on its current state. In particular, removes event listeners if
120          * widget is not visible, and attaches them otherwise.
121          * <p>
122          * This method in invoked after syncUI is invoked for the Widget class
123          * using YUI's aop infrastructure.
124          * </p>
125          * @method _syncUIAutohide
126          * @protected
127          */
128         _syncUIAutohide : function () {
130             this._uiSetHostVisibleAutohide(this.get(VISIBLE));
131         },
133         // *** Private Methods *** //
135         /**
136          * Removes event listeners if widget is not visible, and attaches them otherwise.
137          *
138          * @method _uiSetHostVisibleAutohide
139          * @protected
140          */
141         _uiSetHostVisibleAutohide : function (visible) {
143             if (visible) {
144                 //this._attachUIHandlesAutohide();
145                 Y.later(1, this, '_attachUIHandlesAutohide');
146             } else {
147                 this._detachUIHandlesAutohide();
148             }
149         },
151         /**
152          * Iterates through all objects in the hideOn attribute and creates event listeners.
153          *
154          * @method _attachUIHandlesAutohide
155          * @protected
156          */
157         _attachUIHandlesAutohide : function () {
159             if (this._uiHandlesAutohide) { return; }
161             var bb = this.get(BOUNDING_BOX),
162                 hide = Y.bind(this.hide,this),
163                 uiHandles = [],
164                 self = this,
165                 hideOn = this.get('hideOn'),
166                 i = 0,
167                 o = {node: undefined, ev: undefined, keyCode: undefined};
169                 //push all events on which the widget should be hidden
170                 for (; i < hideOn.length; i++) {
172                     o.node = hideOn[i].node;
173                     o.ev = hideOn[i].eventName;
174                     o.keyCode = hideOn[i].keyCode;
176                     //no keycode or node defined
177                     if (!o.node && !o.keyCode && o.ev) {
178                         uiHandles.push(bb.on(o.ev, hide));
179                     }
181                     //node defined, no keycode (not a keypress)
182                     else if (o.node && !o.keyCode && o.ev) {
183                         uiHandles.push(o.node.on(o.ev, hide));
184                     }
186                     //node defined, keycode defined, event defined (its a key press)
187                     else if (o.node && o.keyCode && o.ev) {
188                         uiHandles.push(o.node.on(o.ev, hide, o.keyCode));
189                     }
191                     else {
192                         Y.log('The event with name "'+o.ev+'" could not be attached.');
193                     }
195                 }
197             this._uiHandlesAutohide = uiHandles;
198         },
200         /**
201          * Detaches all event listeners created by this extension
202          *
203          * @method _detachUIHandlesAutohide
204          * @protected
205          */
206         _detachUIHandlesAutohide : function () {
208             Y.each(this._uiHandlesAutohide, function(h){
209                 h.detach();
210             });
211             this._uiHandlesAutohide = null;
212         },
214         /**
215          * Default function called when the visibility of the widget changes. Determines
216          * whether to attach or detach event listeners based on the visibility of the widget.
217          *
218          * @method _afterHostVisibleChangeAutohide
219          * @protected
220          */
221         _afterHostVisibleChangeAutohide : function (e) {
223             this._uiSetHostVisibleAutohide(e.newVal);
224         },
226         /**
227          * Default function called when hideOn Attribute is changed. Remove existing listeners and create new listeners.
228          *
229          * @method _afterHideOnChange
230          */
231         _afterHideOnChange : function(e) {
232             this._detachUIHandlesAutohide();
234             if (this.get(VISIBLE)) {
235                 this._attachUIHandlesAutohide();
236             }
237         }
240 Y.WidgetAutohide = WidgetAutohide;
243 }, '3.5.1' ,{requires:['base-build','widget','event-outside','event-key']});