NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / widget-autohide / widget-autohide.js
blob28fcc0d09eecd40fe3edea07fb0d644e4f8957ca
1 /*
2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
8 YUI.add('widget-autohide', function (Y, NAME) {
10 /**
11  * A widget-level extension that provides ability to hide widget when
12  * certain events occur.
13  *
14  * @module widget-autohide
15  * @author eferraiuolo, tilomitra
16  * @since 3.4.0
17  */
20 var WIDGET_AUTOHIDE    = 'widgetAutohide',
21     AUTOHIDE            = 'autohide',
22     CLICK_OUTSIDE     = 'clickoutside',
23     FOCUS_OUTSIDE     = 'focusoutside',
24     DOCUMENT            = 'document',
25     KEY                 = 'key',
26     PRESS_ESCAPE         = 'esc',
27     BIND_UI             = 'bindUI',
28     SYNC_UI             = "syncUI",
29     RENDERED            = "rendered",
30     BOUNDING_BOX        = "boundingBox",
31     VISIBLE             = "visible",
32     CHANGE              = 'Change',
34     getCN               = Y.ClassNameManager.getClassName;
36 /**
37  * The WidgetAutohide class provides the hideOn attribute which can
38  * be used to hide the widget when certain events occur.
39  *
40  * @class WidgetAutohide
41  * @param {Object} config User configuration object
42  */
43 function WidgetAutohide(config) {
44     Y.after(this._bindUIAutohide, this, BIND_UI);
45     Y.after(this._syncUIAutohide, this, SYNC_UI);
48     if (this.get(RENDERED)) {
49         this._bindUIAutohide();
50         this._syncUIAutohide();
51     }
55 /**
56 * Static property used to define the default attribute
57 * configuration introduced by WidgetAutohide.
59 * @property ATTRS
60 * @static
61 * @type Object
63 WidgetAutohide.ATTRS = {
66     /**
67      * @attribute hideOn
68      * @type array
69      *
70      * @description An array of objects corresponding to the nodes, events, and keycodes to hide the widget on.
71      * The implementer can supply an array of objects, with each object having the following properties:
72      * <p>eventName: (string, required): The eventName to listen to.</p>
73      * <p>node: (Y.Node, optional): The Y.Node that will fire the event (defaults to the boundingBox of the widget)</p>
74      * <p>keyCode: (string, optional): If listening for key events, specify the keyCode</p>
75      * <p>By default, this attribute consists of one object which will cause the widget to hide if the
76      * escape key is pressed.</p>
77      */
78     hideOn: {
79         validator: Y.Lang.isArray,
80         valueFn  : function() {
81             return [
82                 {
83                     node: Y.one(DOCUMENT),
84                     eventName: KEY,
85                     keyCode: PRESS_ESCAPE
86                 }
87             ];
88         }
89     }
92 WidgetAutohide.prototype = {
93     // *** Instance Members *** //
95         _uiHandlesAutohide : null,
97         // *** Lifecycle Methods *** //
99         destructor : function () {
101             this._detachUIHandlesAutohide();
102         },
104         /**
105          * Binds event listeners to the widget.
106          * <p>
107          * This method in invoked after bindUI is invoked for the Widget class
108          * using YUI's aop infrastructure.
109          * </p>
110          * @method _bindUIAutohide
111          * @protected
112          */
113         _bindUIAutohide : function () {
115             this.after(VISIBLE+CHANGE, this._afterHostVisibleChangeAutohide);
116             this.after("hideOnChange", this._afterHideOnChange);
117         },
119         /**
120          * Syncs up the widget based on its current state. In particular, removes event listeners if
121          * widget is not visible, and attaches them otherwise.
122          * <p>
123          * This method in invoked after syncUI is invoked for the Widget class
124          * using YUI's aop infrastructure.
125          * </p>
126          * @method _syncUIAutohide
127          * @protected
128          */
129         _syncUIAutohide : function () {
131             this._uiSetHostVisibleAutohide(this.get(VISIBLE));
132         },
134         // *** Private Methods *** //
136         /**
137          * Removes event listeners if widget is not visible, and attaches them otherwise.
138          *
139          * @method _uiSetHostVisibleAutohide
140          * @protected
141          */
142         _uiSetHostVisibleAutohide : function (visible) {
144             if (visible) {
145                 //this._attachUIHandlesAutohide();
146                 Y.later(1, this, '_attachUIHandlesAutohide');
147             } else {
148                 this._detachUIHandlesAutohide();
149             }
150         },
152         /**
153          * Iterates through all objects in the hideOn attribute and creates event listeners.
154          *
155          * @method _attachUIHandlesAutohide
156          * @protected
157          */
158         _attachUIHandlesAutohide : function () {
160             if (this._uiHandlesAutohide) { return; }
162             var bb = this.get(BOUNDING_BOX),
163                 hide = Y.bind(this.hide,this),
164                 uiHandles = [],
165                 self = this,
166                 hideOn = this.get('hideOn'),
167                 i = 0,
168                 o = {node: undefined, ev: undefined, keyCode: undefined};
170                 //push all events on which the widget should be hidden
171                 for (; i < hideOn.length; i++) {
173                     o.node = hideOn[i].node;
174                     o.ev = hideOn[i].eventName;
175                     o.keyCode = hideOn[i].keyCode;
177                     //no keycode or node defined
178                     if (!o.node && !o.keyCode && o.ev) {
179                         uiHandles.push(bb.on(o.ev, hide));
180                     }
182                     //node defined, no keycode (not a keypress)
183                     else if (o.node && !o.keyCode && o.ev) {
184                         uiHandles.push(o.node.on(o.ev, hide));
185                     }
187                     //node defined, keycode defined, event defined (its a key press)
188                     else if (o.node && o.keyCode && o.ev) {
189                         uiHandles.push(o.node.on(o.ev, hide, o.keyCode));
190                     }
192                     else {
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.13.0', {"requires": ["base-build", "event-key", "event-outside", "widget"]});