76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassYUI.add('event-mouseenter', function(Y) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <p>Adds subscription and delegation support for mouseenter and mouseleave
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * events. Unlike mouseover and mouseout, these events aren't fired from child
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * elements of a subscribed node.</p>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <p>This avoids receiving three mouseover notifications from a setup like</p>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <pre><code>div#container > p > a[href]</code></pre>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <p>where</p>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <pre><code>Y.one('#container').on('mouseover', callback)</code></pre>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <p>When the mouse moves over the link, one mouseover event is fired from
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * #container, then when the mouse moves over the p, another mouseover event is
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * fired and bubbles to #container, causing a second notification, and finally
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * when the mouse moves over the link, a third mouseover event is fired and
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * bubbles to #container for a third notification.</p>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * <p>By contrast, using mouseenter instead of mouseover, the callback would be
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * executed only once when the mouse moves over #container.</p>
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @module event
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @submodule event-mouseenter
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassvar domEventProxies = Y.Env.evt.dom_wrappers,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass contains = Y.DOM.contains,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass toArray = Y.Array,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass noop = function () {},
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass config = {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass proxyType: "mouseover",
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass relProperty: "fromElement",
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _notify: function (e, property, notifier) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var el = this._node,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass related = e.relatedTarget || e[property];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (el !== related && !contains(el, related)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass notifier.fire(new Y.DOMEventFacade(e, el,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass domEventProxies['event:' + Y.stamp(el) + e.type]));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass on: function (node, sub, notifier) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var el = Y.Node.getDOMNode(node),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass args = [
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.proxyType,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._notify,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass el,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass null,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.relProperty,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass notifier];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle = Y.Event._attach(args, { facade: false });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // node.on(this.proxyType, notify, null, notifier);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass detach: function (node, sub) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle.detach();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass delegate: function (node, sub, notifier, filter) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var el = Y.Node.getDOMNode(node),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass args = [
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.proxyType,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass noop,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass el,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass null,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass notifier
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle = Y.Event._attach(args, { facade: false });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle.sub.filter = filter;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle.sub.relProperty = this.relProperty;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle.sub._notify = this._filterNotify;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _filterNotify: function (thisObj, args, ce) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass args = args.slice();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (this.args) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass args.push.apply(args, this.args);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var currentTarget = Y.delegate._applyFilter(this.filter, args, ce),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass related = args[0].relatedTarget || args[0][this.relProperty],
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e, i, len, ret, ct;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (currentTarget) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass currentTarget = toArray(currentTarget);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass for (i = 0, len = currentTarget.length && (!e || !e.stopped); i < len; ++i) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ct = currentTarget[0];
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!contains(ct, related)) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e = new Y.DOMEventFacade(args[0], ct, ce);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e.container = Y.one(ce.el);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass e.currentTarget = Y.one(ct);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // TODO: where is notifier? args? this.notifier?
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass ret = args[1].fire(e);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (ret === false) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass break;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass return ret;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass detachDelegate: function (node, sub) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass sub.handle.detach();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass };
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.Event.define("mouseenter", config, true);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.Event.define("mouseleave", Y.merge(config, {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass proxyType: "mouseout",
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass relProperty: "toElement"
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}), true);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass}, '@VERSION@' ,{requires:['event-synthetic']});