API Docs for: 0.0.1
Show:

File: src/event-dom/extra/focusnode.js

"use strict";

/**
 * Adds the `focusnode` event as a DOM-event to event-dom. more about DOM-events:
 * http://www.smashingmagazine.com/2013/11/12/an-introduction-to-dom-events/
 *
 *
 * <i>Copyright (c) 2014 ITSA - https://github.com/itsa</i>
 * New BSD License - http://choosealicense.com/licenses/bsd-3-clause/
 *
 * @example
 * Event = require('event-dom/focusnode.js')(window);
 *
 * or
 *
 * @example
 * Event = require('event-dom')(window);
 * require('event-dom/event-focusnode.js')(window);
 *
 * @module event
 * @submodule event-focusnode
 * @class Event
 * @since 0.0.2
*/


var NAME = '[event-focusnode]: ',
    createHashMap = require('js-ext/extra/hashmap.js').createMap;

require('js-ext/lib/object.js');

module.exports = function (window) {

    window._ITSAmodules || Object.protectedProp(window, '_ITSAmodules', createHashMap());

    if (window._ITSAmodules.EventFocusNode) {
        return window._ITSAmodules.EventFocusNode; // EventFocusNode was already created
    }

    var Event = require('../event-dom.js')(window),
        subscriber, previousVnode,

    /*
     * Creates the `focisnode` event.
     *
     * @method setupFocusNode
     * @private
     * @since 0.0.2
     */
    setupFocusNode = function() {
        // create only after subscribing to the `hover`-event
        subscriber = Event.after('focus', function(e) {
            var targetVnode = e.target.vnode,
                vnode = targetVnode,
                alreadyFocussed;
            if (vnode) {
                do {
                    alreadyFocussed = previousVnode && vnode.contains(previousVnode);
                    alreadyFocussed || Event.emit(vnode.domNode, 'UI:focusnode', e);
/*jshint boss:true */
                } while (!alreadyFocussed && (vnode=vnode.vParent));
/*jshint boss:false */
            }
            previousVnode = targetVnode;
        });
    },

    /*
     * Removes the `focusnode` event. Because there are no subscribers anymore.
     *
     * @method teardownFocusNode
     * @private
     * @since 0.0.2
     */
    teardownFocusNode = function() {
        // check if there aren't any subscribers anymore.
        // in that case, we detach the `mouseover` lister because we don't want to
        // loose performance.
        if (!Event._subs['UI:focusnode']) {
            console.log(NAME, 'teardownFocusNode: stop listening for blur-event');
            subscriber.detach();
            // reinit notifier, because it is a one-time notifier:
            Event.notify('UI:focusnode', setupFocusNode, Event, true);
        }
    };

    Event.defineEvent('UI:focusnode').unPreventable();

    Event.notify('UI:focusnode', setupFocusNode, Event, true);
    Event.notifyDetach('UI:focusnode', teardownFocusNode, Event);

    Event.noDeepDomEvt('UI:focusnode');

    window._ITSAmodules.EventFocusNode = Event;

    return Event;
};