]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/widget/widget-uievents.js
Release 6.5.0
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / widget / widget-uievents.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-uievents', function(Y) {
9
10 /**
11  * Support for Widget UI Events (Custom Events fired by the widget, which wrap the underlying DOM events - e.g. widget:click, widget:mousedown)
12  *
13  * @module widget
14  * @submodule widget-uievents
15  */
16
17 var BOUNDING_BOX = "boundingBox",
18     Widget = Y.Widget,
19     RENDER = "render",
20     L = Y.Lang,
21     EVENT_PREFIX_DELIMITER = ":",
22
23     //  Map of Node instances serving as a delegation containers for a specific
24     //  event type to Widget instances using that delegation container.
25     _uievts = Y.Widget._uievts = Y.Widget._uievts || {};
26
27 Y.mix(Widget.prototype, {
28
29     /**
30      * Destructor logic for UI event infrastructure,
31      * invoked during Widget destruction.
32      *
33      * @method _destroyUIEvents
34      * @for Widget
35      * @private
36      */
37     _destroyUIEvents: function() {
38
39         var widgetGuid = Y.stamp(this, true);
40
41         Y.each(_uievts, function (info, key) {
42             if (info.instances[widgetGuid]) {
43                 //  Unregister this Widget instance as needing this delegated
44                 //  event listener.
45                 delete info.instances[widgetGuid];
46
47                 //  There are no more Widget instances using this delegated 
48                 //  event listener, so detach it.
49
50                 if (Y.Object.isEmpty(info.instances)) {
51                     info.handle.detach();
52
53                     if (_uievts[key]) {
54                         delete _uievts[key];
55                     }
56                 }
57             }
58         });
59     },
60
61     /**
62      * Map of DOM events that should be fired as Custom Events by the  
63      * Widget instance.
64      *
65      * @property UI_EVENTS
66      * @for Widget
67      * @type Object
68      */
69     UI_EVENTS: Y.Node.DOM_EVENTS,
70
71     /**
72      * Returns the node on which to bind delegate listeners.
73      *
74      * @method _getUIEventNode
75      * @for Widget
76      * @protected
77      */
78     _getUIEventNode: function () {
79         return this.get(BOUNDING_BOX);
80     },
81
82     /**
83      * Binds a delegated DOM event listener of the specified type to the 
84      * Widget's outtermost DOM element to facilitate the firing of a Custom
85      * Event of the same type for the Widget instance.  
86      *
87      * @private
88      * @for Widget 
89      * @method _createUIEvent
90      * @param type {String} String representing the name of the event
91      */
92     _createUIEvent: function (type) {
93
94         var uiEvtNode = this._getUIEventNode(),
95             key = (Y.stamp(uiEvtNode) + type),
96             info = _uievts[key],
97             handle;
98
99         //  For each Node instance: Ensure that there is only one delegated
100         //  event listener used to fire Widget UI events.
101
102         if (!info) {
103
104             handle = uiEvtNode.delegate(type, function (evt) {
105
106                 var widget = Widget.getByNode(this);
107                 //  Make the DOM event a property of the custom event
108                 //  so that developers still have access to it.
109                 widget.fire(evt.type, { domEvent: evt });
110
111             }, "." + Y.Widget.getClassName());
112
113             _uievts[key] = info = { instances: {}, handle: handle };
114         }
115
116         //  Register this Widget as using this Node as a delegation container.
117         info.instances[Y.stamp(this)] = 1;
118     },
119
120     /**
121      * Determines if the specified event is a UI event.
122      *
123      * @private
124      * @method _isUIEvent
125      * @for Widget 
126      * @param type {String} String representing the name of the event
127      * @return {String} Event Returns the name of the UI Event, otherwise 
128      * undefined.
129      */
130     _getUIEvent: function (type) {
131
132         if (L.isString(type)) {
133             var sType = this.parseType(type)[1],
134                 iDelim,
135                 returnVal;
136
137             if (sType) {
138                 // TODO: Get delimiter from ET, or have ET support this.
139                 iDelim = sType.indexOf(EVENT_PREFIX_DELIMITER);
140                 if (iDelim > -1) {
141                     sType = sType.substring(iDelim + EVENT_PREFIX_DELIMITER.length);
142                 }
143
144                 if (this.UI_EVENTS[sType]) {
145                     returnVal = sType;
146                 }
147             }
148
149             return returnVal;
150         }
151     },
152
153     /**
154      * Sets up infrastructure required to fire a UI event.
155      * 
156      * @private
157      * @method _initUIEvent
158      * @for Widget
159      * @param type {String} String representing the name of the event
160      * @return {String}     
161      */
162     _initUIEvent: function (type) {
163         var sType = this._getUIEvent(type),
164             queue = this._uiEvtsInitQueue || {};
165
166         if (sType && !queue[sType]) {
167
168             this._uiEvtsInitQueue = queue[sType] = 1;
169
170             this.after(RENDER, function() { 
171                 this._createUIEvent(sType);
172                 delete this._uiEvtsInitQueue[sType];
173             });
174         }
175     },
176
177     //  Override of "on" from Base to facilitate the firing of Widget events
178     //  based on DOM events of the same name/type (e.g. "click", "mouseover").
179     //  Temporary solution until we have the ability to listen to when 
180     //  someone adds an event listener (bug 2528230)
181     on: function (type) {
182         this._initUIEvent(type);
183         return Widget.superclass.on.apply(this, arguments);
184     },
185
186     //  Override of "publish" from Base to facilitate the firing of Widget events
187     //  based on DOM events of the same name/type (e.g. "click", "mouseover").    
188     //  Temporary solution until we have the ability to listen to when 
189     //  someone publishes an event (bug 2528230)     
190     publish: function (type, config) {
191         var sType = this._getUIEvent(type);
192         if (sType && config && config.defaultFn) {
193             this._initUIEvent(sType);
194         }        
195         return Widget.superclass.publish.apply(this, arguments);
196     }
197
198 }, true); // overwrite existing EventTarget methods
199
200
201 }, '3.3.0' ,{requires:['widget-base', 'node-event-delegate']});