2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
8 YUI.add('event-mouseenter', function(Y) {
11 * Adds support for mouseenter/mouseleave events
13 * @submodule event-mouseenter
18 plugins = Y.Env.evt.plugins,
24 on: function(type, fn, el) {
26 var args = Y.Array(arguments, 0, true),
31 if (Lang.isString(el)) {
33 // Need to use Y.all because if el is a string it could be a
34 // selector that returns a NodeList
38 if (element.size() === 0) { // Not found, check using onAvailable
40 availHandle = Event.onAvailable(el, function() {
42 availHandle.handle = Y.on.apply(Y, args);
44 }, Event, true, false);
53 var sDOMEvent = (type === "mouseenter") ? "mouseover" : "mouseout",
55 // The name of the custom event
56 sEventName = type + ":" + Y.stamp(element) + sDOMEvent,
58 listener = listeners[sEventName],
67 // Bind an actual DOM event listener that will call the
71 domEventHandle = Y.on(sDOMEvent, Y.rbind(Event._fireMouseEnter, Y, sEventName), element);
73 // Hook into the _delete method for the Custom Event wrapper of this
74 // DOM Event in order to clean up the 'listeners' map and unsubscribe
75 // the associated Custom Event listeners fired by this DOM event
76 // listener if/when the user calls "purgeElement" OR removes all
77 // listeners of the Custom Event.
79 Y.after(function (sub) {
81 if (domEventHandle.sub == sub) {
83 // Delete this event from the map of known mouseenter
84 // and mouseleave listeners
85 delete listeners[sEventName];
88 // Unsubscribe all listeners of the Custom Event fired
90 Y.detachAll(sEventName);
94 }, domEventHandle.evt, "_delete");
98 listener.handle = domEventHandle;
100 listeners[sEventName] = listener;
104 nListeners = listener.count;
106 listener.count = nListeners ? (nListeners + 1) : 1;
108 args[0] = sEventName;
110 // Remove the element from the args
113 // Subscribe to the custom event
114 ceHandle = Y.on.apply(Y, args);
116 // Hook into the detach method of the handle in order to clean up the
117 // 'listeners' map and remove the associated DOM event handler
118 // responsible for firing this Custom Event if all listener for this
119 // event have been removed.
121 Y.after(function () {
123 listener.count = (listener.count - 1);
125 if (listener.count === 0) {
126 listener.handle.detach();
129 }, ceHandle, "detach");
139 Event._fireMouseEnter = function (e, eventName) {
141 var relatedTarget = e.relatedTarget,
142 currentTarget = e.currentTarget;
144 if (currentTarget !== relatedTarget &&
145 !currentTarget.contains(relatedTarget)) {
147 Y.publish(eventName, {
148 contextFn: function() {
149 return currentTarget;
153 Y.fire(eventName, e);
161 * Sets up a "mouseenter" listener—a listener that is called the first time
162 * the user's mouse enters the specified element(s).
165 * @param type {string} "mouseenter"
166 * @param fn {function} The method the event invokes.
167 * @param el {string|node} The element(s) to assign the listener to.
168 * @param spec {string} Optional. String representing a selector that must
169 * match the target of the event in order for the listener to be called.
170 * @return {EventHandle} the detach handle
173 plugins.mouseenter = eventConfig;
176 * Sets up a "mouseleave" listener—a listener that is called the first time
177 * the user's mouse leaves the specified element(s).
180 * @param type {string} "mouseleave"
181 * @param fn {function} The method the event invokes.
182 * @param el {string|node} The element(s) to assign the listener to.
183 * @param spec {string} Optional. String representing a selector that must
184 * match the target of the event in order for the listener to be called.
185 * @return {EventHandle} the detach handle
188 plugins.mouseleave = eventConfig;
191 }, '3.0.0' ,{requires:['node-base']});