index.js
function DragTabs($el, options) {
  // we are an event emitter
  assign(this, createEmitter());

  this.options = options || {};
  this.$el = $el;

  this._moveTab = bind(this._moveTab, this);

  this._onDragstart = bind(this._onDragstart, this);
  this._onDragend = bind(this._onDragend, this);
  this._onDrop = bind(this._onDrop, this);

  this._init();

  this.update();
}
function DragTabs($el, options) {
  // we are an event emitter
  assign(this, createEmitter());

  this.options = options || {};
  this.$el = $el;

  this._moveTab = bind(this._moveTab, this);

  this._onDragstart = bind(this._onDragstart, this);
  this._onDragend = bind(this._onDragend, this);
  this._onDrop = bind(this._onDrop, this);

  this._init();

  this.update();
}
function DragTabs ( $el , options ) { // we are an event emitter assign ( this , createEmitter ( ) ) ; this . options = options || { } ; this . $el = $el ; this . _moveTab = bind ( this . _moveTab , this ) ; this . _onDragstart = bind ( this . _onDragstart , this ) ; this . _onDragend = bind ( this . _onDragend , this ) ; this . _onDrop = bind ( this . _onDrop , this ) ; this . _init ( ) ; this . update ( ) ; }
This component provides the infrastructure needed to move tabs around by dragging.

It's not this component's responsibility to the actual moving of the tab, but exposing an event based
interface that communicates when and where the tab dragging should happen.

It makes sure all the tabs inside the intended container are draggable,
ignoring the ones that are declared as so.

The component is an event emitter and it emits the following events:
- 'drag' is fired everytime there is a new position
- 'end' is always fired at the end of the drag
- 'cancel' is only fired when the dragging is canceled

The three events are emitted with the following context:

```js
var context = {
dragTab: {HTMLElement},
newIndex: {Number}
};
```

@example:
(1) provide a tabs-container:

var $el = (
<div>
<ul class="my-tabs-container">
<li class="my-tab"></li>
<li class="my-tab"></li>
<li class="my-tab ignore-me"></li>
</ul>
</div>
);


(2) initialize dragTabs:

var dragger = dragTabs(tabBarNode, {
selectors: {
tabsContainer: '.my-tabs-container',
tab: '.my-tab',
ignore: '.ignore-me'
}
});


(3) listen to the drag event:

dragger.on('drag', function(context) {
var dragTab = context.dragTab,
newIndex = context.newIndex;

// tab dragging logic
});


(4) update the dragger if tabs change and or the tab container resizes:

dragger.update();


@param  {DOMElement} el
@param  {Object} options
@param  {Object} options.selectors
@param  {String} options.selectors.tabsContainer the container all tabs are contained in
@param  {String} options.selectors.tab a single tab inside the tab container
@param  {String} options.selectors.ignore tabs that should be ignored during scroll left/right
@param  {String} [options.showPreview=true] whether to show or hide the drag preview
This component provides the infrastructure needed to move tabs around by dragging .