function HoverFix(elementRegistry, eventBus, injector) {

  var self = this;

  var dragging = injector.get('dragging', false);

  /**
   * Make sure we are god damn hovering!
   *
   * @param {Event} dragging event
   */
  function ensureHover(event) {

    if (event.hover) {
      return;
    }

    var originalEvent = event.originalEvent;

    var gfx = self._findTargetGfx(originalEvent);

    var element = gfx && elementRegistry.get(gfx);

    if (gfx && element) {

      // 1) cancel current mousemove
      event.stopPropagation();

      // 2) emit fake hover for new target
      dragging.hover({ element: element, gfx: gfx });

      // 3) re-trigger move event
      dragging.move(originalEvent);
    }
  }


  if (dragging) {

    /**
     * We wait for a specific sequence of events before
     * emitting a fake drag.hover event.
     *
     * Event Sequence:
     *
     * drag.start
     * drag.move >> ensure we are hovering
     */
    eventBus.on('drag.start', function(event) {

      eventBus.once('drag.move', HIGH_PRIORITY, function(event) {

        ensureHover(event);

      });

    });
  }


  /**
   * We make sure that element.out is always fired, even if the
   * browser swallows an element.out event.
   *
   * Event sequence:
   *
   * element.hover
   * (element.out >> sometimes swallowed)
   * element.hover >> ensure we fired element.out
   */
  (function() {
    var hoverGfx;
    var hover;

    eventBus.on('element.hover', function(event) {

      // (1) remember current hover element
      hoverGfx = event.gfx;
      hover = event.element;
    });

    eventBus.on('element.hover', HIGH_PRIORITY, function(event) {

      // (3) am I on an element still?
      if (hover) {

        // (4) that is a problem, gotta "simulate the out"
        eventBus.fire('element.out', {
          element: hover,
          gfx: hoverGfx
        });
      }

    });

    eventBus.on('element.out', function() {

      // (2) unset hover state if we correctly outed us *GG*
      hoverGfx = null;
      hover = null;
    });

  })();

  this._findTargetGfx = function(event) {
    var position,
        target;

    if (!(event instanceof MouseEvent)) {
      return;
    }

    position = toPoint(event);

    // damn expensive operation, ouch!
    target = document.elementFromPoint(position.x, position.y);

    return getGfx(target);
  };

}
/**
 * Browsers may swallow certain events (hover, out ...) if users are to
 * fast with the mouse.
 *
 * @see http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event
 *
 * The fix implemented in this component ensure that we
 *
 * 1) have a hover state after a successful drag.move event
 * 2) have an out event when dragging leaves an element
 *
 * @param {ElementRegistry} elementRegistry
 * @param {EventBus} eventBus
 * @param {Injector} injector
 */
Browsers may swallow certain events (hover, out ...) if users are to
fast with the mouse.



The fix implemented in this component ensure that we

1) have a hover state after a successful drag.move event
2) have an out event when dragging leaves an element


Browsers may swallow certain events ( hover out ... ) if users are to fast with the mouse . The fix implemented in this component ensure that we 1 ) have a hover state after a successful drag . move event 2 ) have an out event when dragging leaves an element
function HoverFix(elementRegistry, eventBus, injector) {
  var self = this;
  var dragging = injector.get('dragging', false);
  function ensureHover(event) {
    if (event.hover) {
      return;
    }
    var originalEvent = event.originalEvent;
    var gfx = self._findTargetGfx(originalEvent);
    var element = gfx && elementRegistry.get(gfx);
    if (gfx && element) {
      event.stopPropagation();
      dragging.hover({ element: element, gfx: gfx });
      dragging.move(originalEvent);
    }
  }
  if (dragging) {
    eventBus.on('drag.start', function(event) {
      eventBus.once('drag.move', HIGH_PRIORITY, function(event) {
        ensureHover(event);
      });
    });
  }
  (function() {
    var hoverGfx;
    var hover;
    eventBus.on('element.hover', function(event) {
      hoverGfx = event.gfx;
      hover = event.element;
    });
    eventBus.on('element.hover', HIGH_PRIORITY, function(event) {
      if (hover) {
        eventBus.fire('element.out', {
          element: hover,
          gfx: hoverGfx
        });
      }
    });
    eventBus.on('element.out', function() {
      hoverGfx = null;
      hover = null;
    });
  })();
  this._findTargetGfx = function(event) {
    var position,
        target;
    if (!(event instanceof MouseEvent)) {
      return;
    }
    position = toPoint(event);
    target = document.elementFromPoint(position.x, position.y);
    return getGfx(target);
  };
}
function HoverFix ( elementRegistry , eventBus , injector ) { var self = this ; var dragging = injector . get ( 'dragging' , false ) ; function ensureHover ( event ) { if ( event . hover ) { return ; } var originalEvent = event . originalEvent ; var gfx = self . _findTargetGfx ( originalEvent ) ; var element = gfx && elementRegistry . get ( gfx ) ; if ( gfx && element ) { event . stopPropagation ( ) ; dragging . hover ( { element : element , gfx : gfx } ) ; dragging . move ( originalEvent ) ; } } if ( dragging ) { eventBus . on ( 'drag.start' , function ( event ) { eventBus . once ( 'drag.move' , HIGH_PRIORITY , function ( event ) { ensureHover ( event ) ; } ) ; } ) ; } ( function ( ) { var hoverGfx ; var hover ; eventBus . on ( 'element.hover' , function ( event ) { hoverGfx = event . gfx ; hover = event . element ; } ) ; eventBus . on ( 'element.hover' , HIGH_PRIORITY , function ( event ) { if ( hover ) { eventBus . fire ( 'element.out' , { element : hover , gfx : hoverGfx } ) ; } } ) ; eventBus . on ( 'element.out' , function ( ) { hoverGfx = null ; hover = null ; } ) ; } ) ( ) ; this . _findTargetGfx = function ( event ) { var position , target ; if ( ! ( event instanceof MouseEvent ) ) { return ; } position = toPoint ( event ) ; target = document . elementFromPoint ( position . x , position . y ) ; return getGfx ( target ) ; } ; }
Browsers may swallow certain events (hover, out ...) if users are to
 fast with the mouse.
Browsers may swallow certain events ( hover out ... ) if users are to fast with the mouse .
/**
   * Make sure we are god damn hovering!
   *
   * @param {Event} dragging event
   */ // 1) cancel current mousemove // 2) emit fake hover for new target // 3) re-trigger move event /**
     * We wait for a specific sequence of events before
     * emitting a fake drag.hover event.
     *
     * Event Sequence:
     *
     * drag.start
     * drag.move >> ensure we are hovering
     */ /**
   * We make sure that element.out is always fired, even if the
   * browser swallows an element.out event.
   *
   * Event sequence:
   *
   * element.hover
   * (element.out >> sometimes swallowed)
   * element.hover >> ensure we fired element.out
   */ // (1) remember current hover element // (3) am I on an element still? // (4) that is a problem, gotta "simulate the out" // (2) unset hover state if we correctly outed us *GG* // damn expensive operation, ouch!