]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/javascript/yui/build/event-delegate/event-delegate-debug.js
Release 6.2.1
[Github/sugarcrm.git] / include / javascript / yui / build / event-delegate / event-delegate-debug.js
1 /*
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.8.0r4
6 */
7 /**
8  * Augments the Event Utility with a <code>delegate</code> method that 
9  * facilitates easy creation of delegated event listeners.  (Note: Using CSS 
10  * selectors as the filtering criteria for delegated event listeners requires 
11  * inclusion of the Selector Utility.)
12  *
13  * @module event-delegate
14  * @title Event Utility Event Delegation Module
15  * @namespace YAHOO.util
16  * @requires event
17  */
18
19 (function () {
20
21         var Event = YAHOO.util.Event,
22                 Lang = YAHOO.lang,
23                 delegates = [],
24
25
26                 getMatch = function(el, selector, container) {
27                 
28                         var returnVal;
29                 
30                         if (!el || el === container) {
31                                 returnVal = false;
32                         }
33                         else {
34                                 returnVal = YAHOO.util.Selector.test(el, selector) ? el: getMatch(el.parentNode, selector, container);
35                         }
36                 
37                         return returnVal;
38                 
39                 };
40
41
42         Lang.augmentObject(Event, {
43
44                 /**
45                  * Creates a delegate function used to call event listeners specified 
46                  * via the <code>YAHOO.util.Event.delegate</code> method.
47                  *
48                  * @method _createDelegate
49                  *
50                  * @param {Function} fn        The method (event listener) to call.
51                  * @param {Function|string} filter Function or CSS selector used to 
52                  * determine for what element(s) the event listener should be called.           
53                  * @param {Object}   obj        An arbitrary object that will be 
54                  *                             passed as a parameter to the listener.
55                  * @param {Boolean|object}  overrideContext  If true, the value of the 
56                  *                                                      obj parameter becomes the execution context
57                  *                          of the listener. If an object, this object
58                  *                          becomes the execution context.
59                  * @return {Function} Function that will call the event listener 
60                  * specified by the <code>YAHOO.util.Event.delegate</code> method.
61          * @private
62          * @for Event
63                  * @static
64                  */
65                 _createDelegate: function (fn, filter, obj, overrideContext) {
66
67                         return function (event) {
68
69                                 var container = this,
70                                         target = Event.getTarget(event),
71                                         selector = filter,
72
73                                         //      The user might have specified the document object 
74                                         //      as the delegation container, in which case it is not 
75                                         //      nessary to scope the provided CSS selector(s) to the 
76                                         //      delegation container
77                                         bDocument = (container.nodeType === 9),
78
79                                         matchedEl,
80                                         context,
81                                         sID,
82                                         sIDSelector;
83
84
85                                 if (Lang.isFunction(filter)) {
86                                         matchedEl = filter(target);
87                                 }
88                                 else if (Lang.isString(filter)) {
89
90                                         if (!bDocument) {
91
92                                                 sID = container.id;
93
94                                                 if (!sID) {
95                                                         sID = Event.generateId(container);
96                                                 }                                               
97
98                                                 //      Scope all selectors to the container
99                                                 sIDSelector = ("#" + sID + " ");
100                                                 selector = (sIDSelector + filter).replace(/,/gi, ("," + sIDSelector));
101
102                                         }
103
104
105                                         if (YAHOO.util.Selector.test(target, selector)) {
106                                                 matchedEl = target;
107                                         }
108                                         else if (YAHOO.util.Selector.test(target, ((selector.replace(/,/gi, " *,")) + " *"))) {
109
110                                                 //      The target is a descendant of an element matching 
111                                                 //      the selector, so crawl up to find the ancestor that 
112                                                 //      matches the selector
113
114                                                 matchedEl = getMatch(target, selector, container);
115
116                                         }
117
118                                 }
119
120
121                                 if (matchedEl) {
122
123                                         //      The default context for delegated listeners is the 
124                                         //      element that matched the filter.
125
126                                         context = matchedEl;
127
128                             if (overrideContext) {
129                                 if (overrideContext === true) {
130                                     context = obj;
131                                 } else {
132                                     context = overrideContext;
133                                 }
134                             }
135
136                                         //      Call the listener passing in the container and the 
137                                         //      element that matched the filter in case the user 
138                                         //      needs those.
139
140                                         return fn.call(context, event, matchedEl, container, obj);
141
142                                 }
143
144                         };
145
146                 },
147
148
149         /**
150          * Appends a delegated event listener.  Delegated event listeners 
151                  * receive three arguments by default: the DOM event, the element  
152                  * specified by the filtering function or CSS selector, and the 
153                  * container element (the element to which the event listener is 
154                  * bound).  (Note: Using the delegate method requires the event-delegate 
155                  * module.  Using CSS selectors as the filtering criteria for delegated 
156                  * event listeners requires inclusion of the Selector Utility.)
157          *
158          * @method delegate
159          *
160          * @param {String|HTMLElement|Array|NodeList} container An id, an element 
161          *  reference, or a collection of ids and/or elements to assign the 
162          *  listener to.
163          * @param {String}   type     The type of event listener to append
164          * @param {Function} fn        The method the event invokes
165                  * @param {Function|string} filter Function or CSS selector used to 
166                  * determine for what element(s) the event listener should be called. 
167                  * When a function is specified, the function should return an 
168                  * HTML element.  Using a CSS Selector requires the inclusion of the 
169                  * CSS Selector Utility.
170          * @param {Object}   obj    An arbitrary object that will be 
171          *                             passed as a parameter to the listener
172          * @param {Boolean|object}  overrideContext  If true, the value of the obj parameter becomes
173          *                             the execution context of the listener. If an
174          *                             object, this object becomes the execution
175          *                             context.
176          * @return {Boolean} Returns true if the action was successful or defered,
177          *                   false if one or more of the elements 
178          *                   could not have the listener attached,
179          *                   or if the operation throws an exception.
180          * @static
181          * @for Event
182          */
183                 delegate: function (container, type, fn, filter, obj, overrideContext) {
184
185                         var sType = type,
186                                 fnMouseDelegate,
187                                 fnDelegate;
188
189
190                         if (Lang.isString(filter) && !YAHOO.util.Selector) {
191                                 YAHOO.log("Using a CSS selector to define the filtering criteria for a delegated listener requires the Selector Utility.", "error", "Event");
192                         return false;
193                         }
194
195
196                         if (type == "mouseenter" || type == "mouseleave") {
197
198                                 if (!Event._createMouseDelegate) {
199                                         YAHOO.log("Delegating a " + type + " event requires the event-mouseenter module.", "error", "Event");
200                                 return false;
201                                 }
202
203                                 //      Look up the real event--either mouseover or mouseout
204                                 sType = Event._getType(type);
205
206                                 fnMouseDelegate = Event._createMouseDelegate(fn, obj, overrideContext);
207
208                                 fnDelegate = Event._createDelegate(function (event, matchedEl, container) {
209
210                                         return fnMouseDelegate.call(matchedEl, event, container);
211
212                                 }, filter, obj, overrideContext);
213
214                         }
215                         else {
216
217                                 fnDelegate = Event._createDelegate(fn, filter, obj, overrideContext);
218
219                         }
220
221                         delegates.push([container, sType, fn, fnDelegate]);
222                         
223                         return Event.on(container, sType, fnDelegate);
224
225                 },
226
227
228         /**
229          * Removes a delegated event listener.
230          *
231          * @method removeDelegate
232          *
233          * @param {String|HTMLElement|Array|NodeList} container An id, an element 
234          *  reference, or a collection of ids and/or elements to remove
235          *  the listener from.
236          * @param {String} type The type of event to remove.
237          * @param {Function} fn The method the event invokes.  If fn is
238          *  undefined, then all event listeners for the type of event are 
239          *  removed.
240          * @return {boolean} Returns true if the unbind was successful, false 
241          *  otherwise.
242          * @static
243          * @for Event
244          */
245                 removeDelegate: function (container, type, fn) {
246
247                         var sType = type,
248                                 returnVal = false,
249                                 index,
250                                 cacheItem;
251
252                         //      Look up the real event--either mouseover or mouseout
253                         if (type == "mouseenter" || type == "mouseleave") {
254                                 sType = Event._getType(type);
255                         }
256
257                         index = Event._getCacheIndex(delegates, container, sType, fn);
258
259                     if (index >= 0) {
260                         cacheItem = delegates[index];
261                     }
262
263
264                     if (container && cacheItem) {
265
266                         returnVal = Event.removeListener(cacheItem[0], cacheItem[1], cacheItem[3]);
267
268                                 if (returnVal) {
269                         delete delegates[index][2];
270                         delete delegates[index][3];
271                         delegates.splice(index, 1);
272                                 }               
273                 
274                     }
275
276                         return returnVal;
277
278                 }
279                 
280         });
281
282 }());
283 YAHOO.register("event-delegate", YAHOO.util.Event, {version: "2.8.0r4", build: "2449"});