New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dragselect

Package Overview
Dependencies
Maintainers
1
Versions
97
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dragselect - npm Package Compare versions

Comparing version 1.8.1 to 1.9.0

.eslintrc.json

8

CHANGELOG.md

@@ -0,1 +1,9 @@

# 1.9.0
- Fix non scrollable document element issue. See [#35](https://github.com/ThibaultJanBeyer/DragSelect/issues/35)
- Added `onDragStartBegin` callback. Helpful for my friends at issue [#24](https://github.com/ThibaultJanBeyer/DragSelect/issues/24)
- Increase performance by calculating the selection rectangle outside of the `_isElementTouching` function. Tested on 30.000 Nodes. The selection is still usable although a bit laggy on 30k nodes.
- Rename `isElementTouching` to private `_isElementTouching`. You also have to pass a `selectionRect` as second argument now instead of just passing the container node. This is not considered a breaking change because that function was not exposed before.
- Add prettier & eslint + prettify code
# 1.8.1

@@ -2,0 +10,0 @@

940

dist/DragSelect.js

@@ -1,2 +0,2 @@

// v 1.8.1
// v 1.9.0
/*

@@ -38,3 +38,4 @@ ____ _____ __ __

** @selectableClass string the class assigned to the elements that can be selected
** @onDragStart function It is fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, befor the setup of event listeners.
** @onDragStartBegin function Is fired when the user clicks in the area. This callback gets the event object. Executed *before* DragSelect function code ran.
** @onDragStart function It is fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, before the setup of event listeners.
** @onDragMove function It is fired when the user drags. This callback gets the event object. Executed before DragSelect function code ran, after getting the current mouse position.

@@ -100,20 +101,18 @@ ** @onElementSelect function It is fired every time an element is selected. This callback gets a property which is the just selected node

* DragSelect Class.
*
*
* @constructor
* @param {Object} options - The options object.
*/
function DragSelect( options ) {
function DragSelect(options) {
this.multiSelectKeyPressed;
this.initialCursorPos = {x: 0, y: 0};
this.newCursorPos = {x: 0, y: 0};
this.previousCursorPos = {x: 0, y: 0};
this.initialCursorPos = { x: 0, y: 0 };
this.newCursorPos = { x: 0, y: 0 };
this.previousCursorPos = { x: 0, y: 0 };
this.initialScroll;
this.selected = [];
this._prevSelected = []; // memory to fix #9
this._prevSelected = []; // memory to fix #9
this._createBindings();
this._setupOptions( options );
this._setupOptions(options);
this.start();
}

@@ -125,3 +124,2 @@

DragSelect.prototype._createBindings = function() {
this._startUp = this._startUp.bind(this);

@@ -131,3 +129,2 @@ this._handleMove = this._handleMove.bind(this);

this._onClick = this._onClick.bind(this);
};

@@ -138,4 +135,3 @@

*/
DragSelect.prototype._setupOptions = function( options ) {
DragSelect.prototype._setupOptions = function(options) {
this.selectedClass = options.selectedClass || 'ds-selected';

@@ -147,9 +143,14 @@ this.hoverClass = options.hoverClass || 'ds-hover';

this.selectables = [];
this._handleSelectables( this.toArray( options.selectables ) );
this._handleSelectables(this.toArray(options.selectables));
this.multiSelectKeys = options.multiSelectKeys || ['ctrlKey', 'shiftKey', 'metaKey'];
this.multiSelectKeys = options.multiSelectKeys || [
'ctrlKey',
'shiftKey',
'metaKey'
];
this.multiSelectMode = options.multiSelectMode || false;
this.autoScrollSpeed = options.autoScrollSpeed || 1;
this.autoScrollSpeed = options.autoScrollSpeed === 0 ? 0 : options.autoScrollSpeed || 1;
this.selectCallback = options.onElementSelect || function() {};
this.unselectCallback = options.onElementUnselect || function() {};
this.onDragStartBegin = options.onDragStartBegin || function() {};
this.moveStartCallback = options.onDragStart || function() {};

@@ -162,6 +163,11 @@ this.moveCallback = options.onDragMove || function() {};

// Area has to have a special position attribute for calculations
if( this.area !== document ) {
var computedArea = getComputedStyle( this.area );
var isPositioned = computedArea.position === 'absolute' || computedArea.position === 'relative' || computedArea.position === 'fixed';
if( !isPositioned ) { this.area.style.position = 'relative'; }
if (this.area !== document) {
var computedArea = getComputedStyle(this.area);
var isPositioned =
computedArea.position === 'absolute' ||
computedArea.position === 'relative' ||
computedArea.position === 'fixed';
if (!isPositioned) {
this.area.style.position = 'relative';
}
}

@@ -171,4 +177,3 @@

this.selector = options.selector || this._createSelector();
this.addClass( this.selector, this.selectorClass );
this.addClass(this.selector, this.selectorClass);
};

@@ -178,3 +183,3 @@

* Add/Remove Selectables also handles css classes and event listeners.
*
*
* @param {Object} selectables - selectable elements.

@@ -184,38 +189,38 @@ * @param {Boolean} remove - if elements should be removed.

*/
DragSelect.prototype._handleSelectables = function( selectables, remove, fromSelection ) {
for ( var index = 0; index < selectables.length; index++ ) {
DragSelect.prototype._handleSelectables = function(
selectables,
remove,
fromSelection
) {
for (var index = 0; index < selectables.length; index++) {
var selectable = selectables[index];
var indexOf = this.selectables.indexOf( selectable );
var indexOf = this.selectables.indexOf(selectable);
if( indexOf < 0 && !remove ) { // add
this.addClass( selectable, this.selectableClass );
selectable.addEventListener( 'click', this._onClick );
this.selectables.push( selectable );
if (indexOf < 0 && !remove) {
// add
this.addClass(selectable, this.selectableClass);
selectable.addEventListener('click', this._onClick);
this.selectables.push(selectable);
// also add to current selection
if( fromSelection && this.selected.indexOf( selectable ) < 0 ) {
this.addClass( selectable, this.selectedClass );
this.selected.push( selectable );
if (fromSelection && this.selected.indexOf(selectable) < 0) {
this.addClass(selectable, this.selectedClass);
this.selected.push(selectable);
}
} else if (indexOf > -1 && remove) {
// remove
}
this.removeClass(selectable, this.hoverClass);
this.removeClass(selectable, this.selectableClass);
selectable.removeEventListener('click', this._onClick);
this.selectables.splice(indexOf, 1);
else if( indexOf > -1 && remove ) { // remove
this.removeClass( selectable, this.hoverClass );
this.removeClass( selectable, this.selectableClass );
selectable.removeEventListener( 'click', this._onClick );
this.selectables.splice( indexOf, 1 );
// also remove from current selection
if( fromSelection && this.selected.indexOf( selectable ) > -1 ) {
this.removeClass( selectable, this.selectedClass );
this.selected.splice( this.selected.indexOf( selectable ), 1 );
if (fromSelection && this.selected.indexOf(selectable) > -1) {
this.removeClass(selectable, this.selectedClass);
this.selected.splice(this.selected.indexOf(selectable), 1);
}
}
}
};

@@ -225,26 +230,35 @@

* Triggers when a node is actively selected.
*
*
* This might be an "onClick" method but it also triggers when
* <button> nodes are pressed via the keyboard.
* Making DragSelect accessible for everyone!
*
*
* @param {Object} selectables - selectable elements.
* @param {Boolean} remove - if elements were removed.
*/
DragSelect.prototype._onClick = function( event ) {
DragSelect.prototype._onClick = function(event) {
if( this.mouseInteraction ) { return; } // fix firefox doubleclick issue
if( this.isRightClick( event ) ) { return; }
if (this.mouseInteraction) {
return;
} // fix firefox doubleclick issue
if (this.isRightClick(event)) {
return;
}
var node = event.target;
if(this.isMultiSelectKeyPressed( event )) { this._prevSelected = this.selected.slice(); } // #9
else { this._prevSelected = []; } // #9
if (this.isMultiSelectKeyPressed(event)) {
this._prevSelected = this.selected.slice();
} // #9
else {
this._prevSelected = [];
} // #9
this.checkIfInsideSelection( true ); // reset selection if no multiselectionkeypressed
this.checkIfInsideSelection(true); // reset selection if no multiselectionkeypressed
if( this.selectables.indexOf( node ) > -1 ) { this.toggle( node ); }
if (this.selectables.indexOf(node) > -1) {
this.toggle(node);
}
this.reset();
};

@@ -254,22 +268,20 @@

* Create the selector node when not provided by options object.
*
*
* @return {Node}
*/
DragSelect.prototype._createSelector = function() {
var selector = document.createElement('div');
var selector = document.createElement( 'div' );
selector.style.position = 'absolute';
if( !this.customStyles ) {
if (!this.customStyles) {
selector.style.background = 'rgba(0, 0, 255, 0.1)';
selector.style.border = '1px solid rgba(0, 0, 255, 0.45)';
selector.style.display = 'none';
selector.style.pointerEvents = 'none'; // fix for issue #8 (ie11+)
selector.style.pointerEvents = 'none'; // fix for issue #8 (ie11+)
}
var _area = this.area === document ? document.body : this.area;
_area.appendChild( selector );
_area.appendChild(selector);
return selector;
};

@@ -284,5 +296,3 @@

DragSelect.prototype.start = function() {
this.area.addEventListener( 'mousedown', this._startUp );
this.area.addEventListener('mousedown', this._startUp);
};

@@ -292,30 +302,39 @@

* Startup when the area is clicked.
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._startUp = function( event ) {
DragSelect.prototype._startUp = function(event) {
if( this.isRightClick( event ) ) { return; }
// callback
this.onDragStartBegin(event);
if (this._breaked) { return false; }
if (this.isRightClick(event)) {
return;
}
this.mouseInteraction = true;
this.selector.style.display = 'block';
if(this.isMultiSelectKeyPressed( event )) { this._prevSelected = this.selected.slice(); } // #9
else { this._prevSelected = []; } // #9
if (this.isMultiSelectKeyPressed(event)) {
this._prevSelected = this.selected.slice();
} // #9
else {
this._prevSelected = [];
} // #9
// move element on location
this._getStartingPositions( event );
this.checkIfInsideSelection( true );
this._getStartingPositions(event);
this.checkIfInsideSelection(true);
this.selector.style.display = 'none'; // hidden unless moved, fix for issue #8
this.selector.style.display = 'none'; // hidden unless moved, fix for issue #8
// callback
this.moveStartCallback( event );
if( this._breaked ) { return false; }
this.moveStartCallback(event);
if (this._breaked) { return false; }
// event listeners
this.area.removeEventListener( 'mousedown', this._startUp );
this.area.addEventListener( 'mousemove', this._handleMove );
document.addEventListener( 'mouseup', this.reset );
this.area.removeEventListener('mousedown', this._startUp);
this.area.addEventListener('mousemove', this._handleMove);
document.addEventListener('mouseup', this.reset);
};

@@ -325,16 +344,17 @@

* Check if some multiselection modifier key is pressed
*
*
* @param {Object} event - The event object.
* @return {Boolean} this.isMultiSelectKeyPressed
*/
DragSelect.prototype.isMultiSelectKeyPressed = function( event ) {
DragSelect.prototype.isMultiSelectKeyPressed = function(event) {
this.multiSelectKeyPressed = false;
if (this.multiSelectMode){
if (this.multiSelectMode) {
this.multiSelectKeyPressed = true;
} else {
for ( var index = 0; index < this.multiSelectKeys.length; index++ ) {
for (var index = 0; index < this.multiSelectKeys.length; index++) {
var mKey = this.multiSelectKeys[index];
if( event[mKey] ) { this.multiSelectKeyPressed = true; }
if (event[mKey]) {
this.multiSelectKeyPressed = true;
}
}

@@ -344,3 +364,2 @@ }

return this.multiSelectKeyPressed;
};

@@ -350,10 +369,12 @@

* Grabs the starting position of all needed elements
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._getStartingPositions = function( event ) {
DragSelect.prototype._getStartingPositions = function(event) {
this.initialCursorPos = this.newCursorPos = this._getCursorPos(
event,
this.area
);
this.initialScroll = this.getScroll(this.area);
this.initialCursorPos = this.newCursorPos = this._getCursorPos( event, this.area );
this.initialScroll = this.getScroll( this.area );
var selectorPos = {};

@@ -364,7 +385,5 @@ selectorPos.x = this.initialCursorPos.x + this.initialScroll.x;

selectorPos.h = 0;
this.updatePos( this.selector, selectorPos );
this.updatePos(this.selector, selectorPos);
};
// Movements/Sizing of selection

@@ -375,22 +394,22 @@ //////////////////////////////////////////////////////////////////////////////////////

* Handles what happens while the mouse is moved
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._handleMove = function( event ) {
DragSelect.prototype._handleMove = function(event) {
var selectorPos = this.getPosition(event);
var selectorPos = this.getPosition( event );
// callback
this.moveCallback( event );
if( this._breaked ) { return false; }
this.moveCallback(event);
if (this._breaked) {
return false;
}
this.selector.style.display = 'block'; // hidden unless moved, fix for issue #8
this.selector.style.display = 'block'; // hidden unless moved, fix for issue #8
// move element on location
this.updatePos( this.selector, selectorPos );
this.updatePos(this.selector, selectorPos);
this.checkIfInsideSelection();
// scroll area if area is scrollable
this._autoScroll( event );
this._autoScroll(event);
};

@@ -400,10 +419,9 @@

* Calculates and returns the exact x,y w,h positions of the selector element
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype.getPosition = function( event ) {
DragSelect.prototype.getPosition = function(event) {
var cursorPosNew = this._getCursorPos(event, this.area);
var scrollNew = this.getScroll(this.area);
var cursorPosNew = this._getCursorPos( event, this.area );
var scrollNew = this.getScroll( this.area );
// save for later retrieval

@@ -429,3 +447,3 @@ this.newCursorPos = cursorPosNew;

* by +10px width to fake a negative sizing.
*
*
* One solution to this problem is using css-transforms scale() with

@@ -435,3 +453,3 @@ * transform-origin of top left. BUT we can’t use this since it will size

* get inanely huge. Also transforms are not widely supported in IE.
*
*
* Example #1:

@@ -449,3 +467,3 @@ * Unfortunately, things get even more complicated when we are inside a scrollable

* 3. selectorPos.w = cursorPosNew.x (5) - initialCursorPos.x (0) + scrollAmount.x (10) === 15;
*
*
* let’s say after that movement we now scroll 20px to the left and move our cursor by 30px to the left:

@@ -455,7 +473,7 @@ * 1b. cursorPosNew.x (-30) > initialCursorPos.x (0) - scrollAmount.x (-20) === -30 > -20 === false;

* === -50; // move left position to cursor (for more info see Problem #1)
* 3b. selectorPos.w = initialCursorPos.x (0) - cursorPosNew.x (-30) - scrollAmount.x (-20)
* 3b. selectorPos.w = initialCursorPos.x (0) - cursorPosNew.x (-30) - scrollAmount.x (-20)
* === 0--30--20 === 0+30+20 === 50; // scale width to original left position (for more info see Problem #1)
*
*
* same thing has to be done for top/bottom
*
*
* I hope that makes sence, try stuff out and play around with variables to get a hang of it.

@@ -466,16 +484,18 @@ */

// right
if( cursorPosNew.x > this.initialCursorPos.x - scrollAmount.x ) { // 1.
selectorPos.x = this.initialCursorPos.x + this.initialScroll.x; // 2.
selectorPos.w = cursorPosNew.x - this.initialCursorPos.x + scrollAmount.x; // 3.
// left
} else { // 1b.
selectorPos.x = cursorPosNew.x + scrollNew.x; // 2b.
selectorPos.w = this.initialCursorPos.x - cursorPosNew.x - scrollAmount.x; // 3b.
if (cursorPosNew.x > this.initialCursorPos.x - scrollAmount.x) {
// 1.
selectorPos.x = this.initialCursorPos.x + this.initialScroll.x; // 2.
selectorPos.w = cursorPosNew.x - this.initialCursorPos.x + scrollAmount.x; // 3.
// left
} else {
// 1b.
selectorPos.x = cursorPosNew.x + scrollNew.x; // 2b.
selectorPos.w = this.initialCursorPos.x - cursorPosNew.x - scrollAmount.x; // 3b.
}
// bottom
if( cursorPosNew.y > this.initialCursorPos.y - scrollAmount.y ) {
if (cursorPosNew.y > this.initialCursorPos.y - scrollAmount.y) {
selectorPos.y = this.initialCursorPos.y + this.initialScroll.y;
selectorPos.h = cursorPosNew.y - this.initialCursorPos.y + scrollAmount.y;
// top
// top
} else {

@@ -487,6 +507,4 @@ selectorPos.y = cursorPosNew.y + scrollNew.y;

return selectorPos;
};
// Colision detection

@@ -497,20 +515,24 @@ //////////////////////////////////////////////////////////////////////////////////////

* Checks if element is inside selection and takes action based on that
*
*
* force handles first clicks and accessibility. Here is user is clicking directly onto
* some element at start, (contrary to later hovers) we can assume that he
* really wants to select/deselect that item.
*
*
* @param {Boolean} force – forces through.
*
* @return {Boolean}
*/
DragSelect.prototype.checkIfInsideSelection = function( force ) {
DragSelect.prototype.checkIfInsideSelection = function(force) {
var anyInside = false;
for( var i = 0, il = this.selectables.length; i < il; i++ ) {
var selectable = this.selectables[i];
if( this.isElementTouching( selectable, this.selector, this.area ) ) {
var scroll = this.getScroll(this.area);
var selectionRect = {
y: this.selector.getBoundingClientRect().top + scroll.y,
x: this.selector.getBoundingClientRect().left + scroll.x,
h: this.selector.offsetHeight,
w: this.selector.offsetWidth
};
if( this._isElementTouching( selectable, selectionRect, scroll ) ) {
this._handleSelection( selectable, force );

@@ -521,7 +543,4 @@ anyInside = true;

}
}
return anyInside;
};

@@ -531,19 +550,19 @@

* Logic when an item is selected
*
*
* @param {Node} item – selected item.
* @param {Boolean} force – forces through.
*/
DragSelect.prototype._handleSelection = function( item, force ) {
DragSelect.prototype._handleSelection = function(item, force) {
if (this.hasClass(item, this.hoverClass) && !force) {
return false;
}
var posInSelectedArray = this.selected.indexOf(item);
if( this.hasClass( item, this.hoverClass ) && !force ) { return false; }
var posInSelectedArray = this.selected.indexOf( item );
if( posInSelectedArray < 0 ) {
this.select( item );
} else if( posInSelectedArray > -1 && this.multiSelectKeyPressed ) {
this.unselect( item );
if (posInSelectedArray < 0) {
this.select(item);
} else if (posInSelectedArray > -1 && this.multiSelectKeyPressed) {
this.unselect(item);
}
this.addClass( item, this.hoverClass );
this.addClass(item, this.hoverClass);
};

@@ -553,12 +572,13 @@

* Logic when an item is de-selected
*
*
* @param {Node} item – selected item.
* @param {Boolean} force – forces through.
*/
DragSelect.prototype._handleUnselection = function( item, force ) {
DragSelect.prototype._handleUnselection = function(item, force) {
if (!this.hasClass(item, this.hoverClass) && !force) {
return false;
}
var posInSelectedArray = this.selected.indexOf(item);
var isInPrevSelection = this._prevSelected.indexOf(item); // #9
if( !this.hasClass( item, this.hoverClass ) && !force ) { return false; }
var posInSelectedArray = this.selected.indexOf( item );
var isInPrevSelection = this._prevSelected.indexOf( item ); // #9
/**

@@ -571,10 +591,9 @@ * Special algorithm for issue #9.

*/
if( posInSelectedArray > -1 && isInPrevSelection < 0 ) {
this.unselect( item );
} else if ( posInSelectedArray < 0 && isInPrevSelection > -1 ) {
this.select( item );
if (posInSelectedArray > -1 && isInPrevSelection < 0) {
this.unselect(item);
} else if (posInSelectedArray < 0 && isInPrevSelection > -1) {
this.select(item);
}
this.removeClass( item, this.hoverClass );
this.removeClass(item, this.hoverClass);
};

@@ -584,18 +603,20 @@

* Adds an item to the selection.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.select = function( item ) {
DragSelect.prototype.select = function(item) {
if (this.selected.indexOf(item) > -1) {
return false;
}
if( this.selected.indexOf(item) > -1) { return false; }
this.selected.push(item);
this.addClass(item, this.selectedClass);
this.selected.push( item );
this.addClass( item, this.selectedClass );
this.selectCallback(item);
if (this._breaked) {
return false;
}
this.selectCallback( item );
if( this._breaked ) { return false; }
return item;
};

@@ -605,18 +626,20 @@

* Removes an item from the selection.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.unselect = function( item ) {
DragSelect.prototype.unselect = function(item) {
if (this.selected.indexOf(item) < 0) {
return false;
}
if( this.selected.indexOf(item) < 0) { return false; }
this.selected.splice(this.selected.indexOf(item), 1);
this.removeClass(item, this.selectedClass);
this.selected.splice( this.selected.indexOf(item), 1 );
this.removeClass( item, this.selectedClass );
this.unselectCallback( item );
if( this._breaked ) { return false; }
this.unselectCallback(item);
if (this._breaked) {
return false;
}
return item;
};

@@ -627,41 +650,35 @@

* If it is already selected = remove, if not = add.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.toggle = function( item ) {
if( this.selected.indexOf( item ) > -1) {
this.unselect( item );
} else {
this.select( item );
}
return item;
};
DragSelect.prototype.toggle = function(item) {
if (this.selected.indexOf(item) > -1) {
this.unselect(item);
} else {
this.select(item);
}
return item;
};
/**
* Checks if element is touched by the selector (and vice-versa)
*
*
* @param {Node} element – item.
* @param {Node} container – selector.
* @param {Node} area – surrounding area.
* @param {Object} selectionRect – Container bounds:
Example: {
y: this.selector.getBoundingClientRect().top + scroll.y,
x: this.selector.getBoundingClientRect().left + scroll.x,
h: this.selector.offsetHeight,
w: this.selector.offsetWidth
};
* @param {Object} scroll – Scroll x, y values.
* @return {Boolean}
*/
DragSelect.prototype.isElementTouching = function( element, container, area ) {
/**
* calculating everything here on every move consumes more performance
* but makes sure to get the right positions even if the containers are
* resized or moved on the fly. This also makes the function kinda context independant.
*/
var scroll = this.getScroll( area );
var containerRect = {
y: container.getBoundingClientRect().top + scroll.y,
x: container.getBoundingClientRect().left + scroll.x,
h: container.offsetHeight || element.getBoundingClientRect().height,
w: container.offsetWidth || element.getBoundingClientRect().width
};
DragSelect.prototype._isElementTouching = function(
element,
selectionRect,
scroll
) {
var elementRect = {

@@ -688,16 +705,13 @@ y: element.getBoundingClientRect().top + scroll.y,

if (
containerRect.x < elementRect.x + elementRect.w &&
containerRect.x + containerRect.w > elementRect.x &&
containerRect.y < elementRect.y + elementRect.h &&
containerRect.h + containerRect.y > elementRect.y
selectionRect.x < elementRect.x + elementRect.w &&
selectionRect.x + selectionRect.w > elementRect.x &&
selectionRect.y < elementRect.y + elementRect.h &&
selectionRect.h + selectionRect.y > elementRect.y
) {
return true; // collision detected!
}
else {
} else {
return false;
}
};
// Autoscroll

@@ -708,16 +722,19 @@ //////////////////////////////////////////////////////////////////////////////////////

* Automatically Scroll the area by selecting
*
*
* @param {Object} event – event object.
*/
DragSelect.prototype._autoScroll = function( event ) {
DragSelect.prototype._autoScroll = function(event) {
var edge = this.isCursorNearEdge(event, this.area);
var edge = this.isCursorNearEdge( event, this.area );
var _area = this.area === document ? document.documentElement || document.body : this.area;
var _area = this.area === document ? this.area.body : this.area;
if( edge === 'top' && _area.scrollTop > 0 ) { _area.scrollTop -= 1 * this.autoScrollSpeed; }
else if( edge === 'bottom' ) { _area.scrollTop += 1 * this.autoScrollSpeed; }
else if( edge === 'left' && _area.scrollLeft > 0 ) { _area.scrollLeft -= 1 * this.autoScrollSpeed; }
else if( edge === 'right' ) { _area.scrollLeft += 1 * this.autoScrollSpeed; }
if (edge === 'top' && _area.scrollTop > 0) {
_area.scrollTop -= 1 * this.autoScrollSpeed;
} else if (edge === 'bottom') {
_area.scrollTop += 1 * this.autoScrollSpeed;
} else if (edge === 'left' && _area.scrollLeft > 0) {
_area.scrollLeft -= 1 * this.autoScrollSpeed;
} else if (edge === 'right') {
_area.scrollLeft += 1 * this.autoScrollSpeed;
}
};

@@ -727,3 +744,3 @@

* Check if the selector is near an edge of the area
*
*
* @param {Object} event – event object.

@@ -733,7 +750,6 @@ * @param {Node} area – the area.

*/
DragSelect.prototype.isCursorNearEdge = function( event, area ) {
DragSelect.prototype.isCursorNearEdge = function(event, area) {
var cursorPosition = this._getCursorPos(event, area);
var areaRect = this.getAreaRect(area);
var cursorPosition = this._getCursorPos( event, area );
var areaRect = this.getAreaRect( area );
var tolerance = {

@@ -744,12 +760,15 @@ x: Math.max(areaRect.width / 10, 30),

if( cursorPosition.y < tolerance.y ) { return 'top'; }
else if( areaRect.height - cursorPosition.y < tolerance.y ) { return 'bottom'; }
else if( areaRect.width - cursorPosition.x < tolerance.x ) { return 'right'; }
else if( cursorPosition.x < tolerance.x ) { return 'left'; }
if (cursorPosition.y < tolerance.y) {
return 'top';
} else if (areaRect.height - cursorPosition.y < tolerance.y) {
return 'bottom';
} else if (areaRect.width - cursorPosition.x < tolerance.x) {
return 'right';
} else if (cursorPosition.x < tolerance.x) {
return 'left';
}
return false;
};
// Ending

@@ -761,12 +780,13 @@ //////////////////////////////////////////////////////////////////////////////////////

*/
DragSelect.prototype.reset = function( event ) {
DragSelect.prototype.reset = function(event) {
this.previousCursorPos = this._getCursorPos(event, this.area);
document.removeEventListener('mouseup', this.reset);
this.area.removeEventListener('mousemove', this._handleMove);
this.area.addEventListener('mousedown', this._startUp);
this.previousCursorPos = this._getCursorPos( event, this.area );
document.removeEventListener( 'mouseup', this.reset );
this.area.removeEventListener( 'mousemove', this._handleMove );
this.area.addEventListener( 'mousedown', this._startUp );
this.callback(this.selected, event);
if (this._breaked) {
return false;
}
this.callback( this.selected, event );
if( this._breaked ) { return false; }
this.selector.style.width = '0';

@@ -776,6 +796,9 @@ this.selector.style.height = '0';

setTimeout(function() { // debounce in order "onClick" to work
this.mouseInteraction = false;
}.bind(this), 100);
setTimeout(
function() {
// debounce in order "onClick" to work
this.mouseInteraction = false;
}.bind(this),
100
);
};

@@ -789,8 +812,10 @@

DragSelect.prototype.break = function() {
this._breaked = true;
setTimeout(function() { // debounce the break should only break once instantly after call
this._breaked = false;
}.bind(this), 100);
setTimeout(
function() {
// debounce the break should only break once instantly after call
this._breaked = false;
}.bind(this),
100
);
};

@@ -802,10 +827,7 @@

DragSelect.prototype.stop = function() {
this.reset();
this.area.removeEventListener( 'mousedown', this._startUp );
document.removeEventListener( 'mouseup', this.reset );
this.area.removeEventListener('mousedown', this._startUp);
document.removeEventListener('mouseup', this.reset);
};
// Usefull methods for user

@@ -816,9 +838,7 @@ //////////////////////////////////////////////////////////////////////////////////////

* Returns the current selected nodes
*
*
* @return {Nodes}
*/
DragSelect.prototype.getSelection = function() {
return this.selected;
};

@@ -829,3 +849,3 @@

* Will be relative to an area including the scroll unless advised otherwise
*
*
* @param {Object} event

@@ -836,10 +856,11 @@ * @param {Node} _area – containing area / this.area if none / document if === false

*/
DragSelect.prototype.getCursorPos = function( event, _area, ignoreScroll ) {
DragSelect.prototype.getCursorPos = function(event, _area, ignoreScroll) {
if (!event) {
return false;
}
if(!event) { return false; }
var area = _area || (_area !== false && this.area);
var pos = this._getCursorPos(event, area);
var scroll = ignoreScroll ? { x: 0, y: 0 } : this.getScroll(area);
var area = _area || _area !== false && this.area;
var pos = this._getCursorPos( event, area );
var scroll = ignoreScroll ? { x: 0, y: 0 } : this.getScroll( area );
return {

@@ -857,3 +878,3 @@ x: pos.x + scroll.x,

* Can add multiple nodes at once, in contrary to .select
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -864,16 +885,22 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.addSelection = function( _nodes, _callback, dontAddToSelectables ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.addSelection = function(
_nodes,
_callback,
dontAddToSelectables
) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
this.select( node );
this.select(node);
}
if( !dontAddToSelectables ) { this.addSelectables( nodes ); }
if( _callback ) { this.callback( this.selected, false ); }
if (!dontAddToSelectables) {
this.addSelectables(nodes);
}
if (_callback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -884,3 +911,3 @@

* Multiple nodes can be given at once, in contrary to unselect
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -891,16 +918,22 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.removeSelection = function( _nodes, _callback, removeFromSelectables ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.removeSelection = function(
_nodes,
_callback,
removeFromSelectables
) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
this.unselect( node );
this.unselect(node);
}
if( removeFromSelectables ) { this.removeSelectables( nodes ); }
if( _callback ) { this.callback( this.selected, false ); }
if (removeFromSelectables) {
this.removeSelectables(nodes);
}
if (_callback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -912,3 +945,3 @@

* Multiple nodes can be given at once.
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -919,23 +952,16 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.toggleSelection = function( _nodes, _callback, _special ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.toggleSelection = function(_nodes, _callback, _special) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
if( this.selected.indexOf( node ) < 0 ) {
this.addSelection( node, _callback, _special );
if (this.selected.indexOf(node) < 0) {
this.addSelection(node, _callback, _special);
} else {
this.removeSelection( node, _callback, _special );
this.removeSelection(node, _callback, _special);
}
}
return this.selected;
};

@@ -945,3 +971,3 @@

* Sets the current selected nodes and optionally run the callback
*
*
* @param {Nodes} _nodes – dom nodes

@@ -952,9 +978,11 @@ * @param {Boolean} runCallback - if callback should be called

*/
DragSelect.prototype.setSelection = function( _nodes, runCallback, dontAddToSelectables ) {
DragSelect.prototype.setSelection = function(
_nodes,
runCallback,
dontAddToSelectables
) {
this.clearSelection();
this.addSelection( _nodes, runCallback, dontAddToSelectables );
this.addSelection(_nodes, runCallback, dontAddToSelectables);
return this.selected;
};

@@ -964,18 +992,18 @@

* Unselect / Deselect all current selected Nodes
*
*
* @param {Boolean} runCallback - if callback should be called
* @return {Array} this.selected, should be empty
*/
DragSelect.prototype.clearSelection = function( runCallback ) {
DragSelect.prototype.clearSelection = function(runCallback) {
var selection = this.selected.slice();
for (var index = 0, il = selection.length; index < il; index++) {
var node = selection[index];
this.unselect( node );
this.unselect(node);
}
if( runCallback ) { this.callback( this.selected, false ); }
if (runCallback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -986,3 +1014,3 @@

* The algorithm makes sure that no node is added twice
*
*
* @param {Nodes} _nodes – dom nodes

@@ -992,8 +1020,6 @@ * @param {Boolean} addToSelection – if elements should also be added to current selection

*/
DragSelect.prototype.addSelectables = function( _nodes, addToSelection ) {
var nodes = this.toArray( _nodes );
this._handleSelectables( nodes, false, addToSelection );
DragSelect.prototype.addSelectables = function(_nodes, addToSelection) {
var nodes = this.toArray(_nodes);
this._handleSelectables(nodes, false, addToSelection);
return _nodes;
};

@@ -1003,9 +1029,7 @@

* Gets all nodes that can be selected
*
*
* @return {Nodes} this.selectables
*/
DragSelect.prototype.getSelectables = function() {
return this.selectables;
};

@@ -1018,3 +1042,3 @@

* thus replacing the original set.
*
*
* @param {Nodes} _nodes – dom nodes

@@ -1025,7 +1049,9 @@ * @param {Boolean} removeFromSelection – if elements should also be removed from current selection

*/
DragSelect.prototype.setSelectables = function( _nodes, removeFromSelection, addToSelection ) {
this.removeSelectables( this.getSelectables(), removeFromSelection );
return this.addSelectables( _nodes, addToSelection );
DragSelect.prototype.setSelectables = function(
_nodes,
removeFromSelection,
addToSelection
) {
this.removeSelectables(this.getSelectables(), removeFromSelection);
return this.addSelectables(_nodes, addToSelection);
};

@@ -1035,3 +1061,3 @@

* Remove nodes from the nodes that can be selected.
*
*
* @param {Nodes} _nodes – dom nodes

@@ -1041,11 +1067,8 @@ * @param {Boolean} removeFromSelection – if elements should also be removed from current selection

*/
DragSelect.prototype.removeSelectables = function( _nodes, removeFromSelection ) {
var nodes = this.toArray( _nodes );
this._handleSelectables( nodes, true, removeFromSelection );
DragSelect.prototype.removeSelectables = function(_nodes, removeFromSelection) {
var nodes = this.toArray(_nodes);
this._handleSelectables(nodes, true, removeFromSelection);
return _nodes;
};
// Helpers

@@ -1058,23 +1081,24 @@ //////////////////////////////////////////////////////////////////////////////////////

* (found @ https://stackoverflow.com/a/2405835)
*
* @param {Object} event
*
* @param {Object} event
* @return {Boolean}
*/
DragSelect.prototype.isRightClick = function( event ) {
DragSelect.prototype.isRightClick = function(event) {
if (!event) {
return false;
}
if( !event ) { return false; }
var isRightMB = false;
if ('which' in event) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
isRightMB = event.which === 3;
} else if ('button' in event) { // IE, Opera
isRightMB = event.button === 2;
if ('which' in event) {
// Gecko (Firefox), WebKit (Safari/Chrome) & Opera
isRightMB = event.which === 3;
} else if ('button' in event) {
// IE, Opera
isRightMB = event.button === 2;
}
return isRightMB;
};
/**

@@ -1084,17 +1108,21 @@ * Adds a class to an element

* all credits to http://clubmate.fi/javascript-adding-and-removing-class-names-from-elements/
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Node} element
*/
DragSelect.prototype.addClass = function( element, classname ) {
DragSelect.prototype.addClass = function(element, classname) {
if (element.classList) {
return element.classList.add(classname);
}
if(element.classList) { return element.classList.add(classname); }
var cn = element.getAttribute('class') || '';
if( cn.indexOf(classname) !== -1 ) { return element; } // test for existance
if( cn !== '' ) { classname = ' ' + classname; } // add a space if the element already has class
element.setAttribute('class', cn+classname);
if (cn.indexOf(classname) !== -1) {
return element;
} // test for existance
if (cn !== '') {
classname = ' ' + classname;
} // add a space if the element already has class
element.setAttribute('class', cn + classname);
return element;
};

@@ -1106,17 +1134,17 @@

* all credits to http://clubmate.fi/javascript-adding-and-removing-class-names-from-elements/
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Node} element
*/
DragSelect.prototype.removeClass = function( element, classname ) {
DragSelect.prototype.removeClass = function(element, classname) {
if (element.classList) {
return element.classList.remove(classname);
}
if(element.classList) { return element.classList.remove(classname); }
var cn = element.getAttribute('class') || '';
var rxp = new RegExp( classname + '\\b', 'g' );
cn = cn.replace( rxp, '' );
var rxp = new RegExp(classname + '\\b', 'g');
cn = cn.replace(rxp, '');
element.setAttribute('class', cn);
return element;
};

@@ -1127,15 +1155,18 @@

* sadly legacy phones/browsers don’t support .classlist so we use this workaround
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Boolean}
*/
DragSelect.prototype.hasClass = function( element, classname ) {
DragSelect.prototype.hasClass = function(element, classname) {
if (element.classList) {
return element.classList.contains(classname);
}
if(element.classList) { return element.classList.contains(classname); }
var cn = element.getAttribute('class') || '';
if( cn.indexOf( classname ) > -1 ) { return true; }
else { return false; }
if (cn.indexOf(classname) > -1) {
return true;
} else {
return false;
}
};

@@ -1146,13 +1177,16 @@

* so user doesn’t have to care.
*
*
* @param {Node} nodes
* @return {array}
*/
DragSelect.prototype.toArray = function( nodes ) {
DragSelect.prototype.toArray = function(nodes) {
if (!nodes) {
return false;
}
if (!nodes.length && this.isElement(nodes)) {
return [nodes];
}
if( !nodes ) { return false; }
if( !nodes.length && this.isElement( nodes ) ) { return [nodes]; }
var array = [];
for ( var i = nodes.length - 1; i >= 0; i-- ) {
for (var i = nodes.length - 1; i >= 0; i--) {
array[i] = nodes[i];

@@ -1162,3 +1196,2 @@ }

return array;
};

@@ -1168,22 +1201,22 @@

* Checks if a node is of type element
* all credits to vikynandha: https://gist.github.com/vikynandha/6539809
*
* all credits to vikynandha: https://gist.github.com/vikynandha/6539809
*
* @param {Node} node
* @return {Boolean}
*/
DragSelect.prototype.isElement = function( node ) {
try { // Using W3 DOM2 (works for FF, Opera and Chrome), also checking for SVGs
DragSelect.prototype.isElement = function(node) {
try {
// Using W3 DOM2 (works for FF, Opera and Chrome), also checking for SVGs
return node instanceof HTMLElement || node instanceof SVGElement;
}
catch( e ){
} catch (e) {
// Browsers not supporting W3 DOM2 don't have HTMLElement and
// an exception is thrown and we end up here. Testing some
// properties that all elements have. (works even on IE7)
return ( typeof node === 'object' ) &&
( node.nodeType === 1 ) &&
( typeof node.style === 'object' ) &&
( typeof node.ownerDocument === 'object' );
return (
typeof node === 'object' &&
node.nodeType === 1 &&
typeof node.style === 'object' &&
typeof node.ownerDocument === 'object'
);
}
};

@@ -1196,3 +1229,3 @@

* Use the public .getCursorPos() from outside, it’s more flexible
*
*
* @param {Object} event

@@ -1202,6 +1235,9 @@ * @param {Node} area – containing area / document if none

*/
DragSelect.prototype._getCursorPos = function( event, area ) {
if(!event) { return { x: 0, y: 0 }; }
DragSelect.prototype._getCursorPos = function(event, area) {
if (!event) {
return { x: 0, y: 0 };
}
var cPos = { // event.clientX/Y fallback for <IE8
var cPos = {
// event.clientX/Y fallback for <IE8
x: event.pageX || event.clientX,

@@ -1211,10 +1247,10 @@ y: event.pageY || event.clientY

var areaRect = this.getAreaRect( area || document );
var docScroll = this.getScroll(); // needed when document is scrollable but area is not
var areaRect = this.getAreaRect(area || document);
var docScroll = this.getScroll(); // needed when document is scrollable but area is not
return { // if it’s constrained in an area the area should be substracted calculate
return {
// if it’s constrained in an area the area should be substracted calculate
x: cPos.x - areaRect.left - docScroll.x,
y: cPos.y - areaRect.top - docScroll.y
};
};

@@ -1224,7 +1260,7 @@

* Returns the starting/initial position of the cursor/selector
*
*
* @return {Object} initialPos.
*/
DragSelect.prototype.getInitialCursorPosition = function() {
return this.initialCursorPos;
return this.initialCursorPos;
};

@@ -1234,3 +1270,3 @@

* Returns the last seen position of the cursor/selector
*
*
* @return {Object} initialPos.

@@ -1248,3 +1284,3 @@ */

DragSelect.prototype.getPreviousCursorPosition = function() {
return this.previousCursorPos;
return this.previousCursorPos;
};

@@ -1260,6 +1296,9 @@

*/
DragSelect.prototype.getCursorPositionDifference = function( usePreviousCursorDifference ) {
DragSelect.prototype.getCursorPositionDifference = function(
usePreviousCursorDifference
) {
var posA = this.getCurrentCursorPosition();
var posB = usePreviousCursorDifference ? this.getPreviousCursorPosition() : this.getInitialCursorPosition();
var posB = usePreviousCursorDifference
? this.getPreviousCursorPosition()
: this.getInitialCursorPosition();

@@ -1270,3 +1309,2 @@ return {

};
};

@@ -1277,14 +1315,20 @@

* If container has no scroll it will return 0
*
*
* @param {Node} area
* @return {Object} scroll X/Y
*/
DragSelect.prototype.getScroll = function( area ) {
DragSelect.prototype.getScroll = function(area) {
var body = {
top: document.body.scrollTop > 0 ? document.body.scrollTop : document.documentElement.scrollTop,
left: document.body.scrollLeft > 0 ? document.body.scrollLeft : document.documentElement.scrollLeft
top:
document.body.scrollTop > 0
? document.body.scrollTop
: document.documentElement.scrollTop,
left:
document.body.scrollLeft > 0
? document.body.scrollLeft
: document.documentElement.scrollLeft
};
var scroll = { // when the rectangle is bound to the document, no scroll is needed
var scroll = {
// when the rectangle is bound to the document, no scroll is needed
y: area && area.scrollTop >= 0 ? area.scrollTop : body.top,

@@ -1295,3 +1339,2 @@ x: area && area.scrollLeft >= 0 ? area.scrollLeft : body.left

return scroll;
};

@@ -1303,14 +1346,26 @@

* except the sizes will be nulled.
*
* @param {Node} area
*
* @param {Node} area
* @return {Object}
*/
DragSelect.prototype.getAreaRect = function( area ) {
if(area === document) {
DragSelect.prototype.getAreaRect = function(area) {
if (area === document) {
var size = {
y: area.documentElement.clientHeight > 0 ? area.documentElement.clientHeight : window.innerHeight,
x: area.documentElement.clientWidth > 0 ? area.documentElement.clientWidth : window.innerWidth
y:
area.documentElement.clientHeight > 0
? area.documentElement.clientHeight
: window.innerHeight,
x:
area.documentElement.clientWidth > 0
? area.documentElement.clientWidth
: window.innerWidth
};
return { top: 0, left: 0, bottom: 0, right: 0, width: size.x, height: size.y };
return {
top: 0,
left: 0,
bottom: 0,
right: 0,
width: size.x,
height: size.y
};
}

@@ -1326,3 +1381,2 @@

};
};

@@ -1333,10 +1387,9 @@

* height values accordingly.
*
*
* @param {Node} node
* @param {Object} pos { x, y, w, h }
*
*
* @return {Node}
*/
DragSelect.prototype.updatePos = function( node, pos ) {
DragSelect.prototype.updatePos = function(node, pos) {
node.style.left = pos.x + 'px';

@@ -1347,24 +1400,23 @@ node.style.top = pos.y + 'px';

return node;
};
// Make exportable
//////////////////////////////////////////////////////////////////////////////////////
// jshint -W117
/* eslint-disable no-undef */
// Module exporting
if ( typeof module !== 'undefined' && module !== null ) {
if (typeof module !== 'undefined' && module !== null) {
module.exports = DragSelect;
// AMD Modules
} else if( typeof define !== 'undefined' && typeof define === 'function' && define ) {
define(function() { return DragSelect; });
// AMD Modules
} else if (
typeof define !== 'undefined' &&
typeof define === 'function' &&
define
) {
define(function() {
return DragSelect;
});
} else {
window.DragSelect = DragSelect;
}

@@ -1,1 +0,1 @@

function DragSelect(e){this.multiSelectKeyPressed,this.initialCursorPos={x:0,y:0},this.newCursorPos={x:0,y:0},this.previousCursorPos={x:0,y:0},this.initialScroll,this.selected=[],this._prevSelected=[],this._createBindings(),this._setupOptions(e),this.start()}DragSelect.prototype._createBindings=function(){this._startUp=this._startUp.bind(this),this._handleMove=this._handleMove.bind(this),this.reset=this.reset.bind(this),this._onClick=this._onClick.bind(this)},DragSelect.prototype._setupOptions=function(e){if(this.selectedClass=e.selectedClass||"ds-selected",this.hoverClass=e.hoverClass||"ds-hover",this.selectorClass=e.selectorClass||"ds-selector",this.selectableClass=e.selectableClass||"ds-selectable",this.selectables=[],this._handleSelectables(this.toArray(e.selectables)),this.multiSelectKeys=e.multiSelectKeys||["ctrlKey","shiftKey","metaKey"],this.multiSelectMode=e.multiSelectMode||!1,this.autoScrollSpeed=e.autoScrollSpeed||1,this.selectCallback=e.onElementSelect||function(){},this.unselectCallback=e.onElementUnselect||function(){},this.moveStartCallback=e.onDragStart||function(){},this.moveCallback=e.onDragMove||function(){},this.callback=e.callback||function(){},this.area=e.area||document,this.customStyles=e.customStyles,this.area!==document){var t=getComputedStyle(this.area);"absolute"===t.position||"relative"===t.position||"fixed"===t.position||(this.area.style.position="relative")}this.selector=e.selector||this._createSelector(),this.addClass(this.selector,this.selectorClass)},DragSelect.prototype._handleSelectables=function(e,t,s){for(var i=0;i<e.length;i++){var o=e[i],r=this.selectables.indexOf(o);r<0&&!t?(this.addClass(o,this.selectableClass),o.addEventListener("click",this._onClick),this.selectables.push(o),s&&this.selected.indexOf(o)<0&&(this.addClass(o,this.selectedClass),this.selected.push(o))):r>-1&&t&&(this.removeClass(o,this.hoverClass),this.removeClass(o,this.selectableClass),o.removeEventListener("click",this._onClick),this.selectables.splice(r,1),s&&this.selected.indexOf(o)>-1&&(this.removeClass(o,this.selectedClass),this.selected.splice(this.selected.indexOf(o),1)))}},DragSelect.prototype._onClick=function(e){if(!this.mouseInteraction&&!this.isRightClick(e)){var t=e.target;this.isMultiSelectKeyPressed(e)?this._prevSelected=this.selected.slice():this._prevSelected=[],this.checkIfInsideSelection(!0),this.selectables.indexOf(t)>-1&&this.toggle(t),this.reset()}},DragSelect.prototype._createSelector=function(){var e=document.createElement("div");return e.style.position="absolute",this.customStyles||(e.style.background="rgba(0, 0, 255, 0.1)",e.style.border="1px solid rgba(0, 0, 255, 0.45)",e.style.display="none",e.style.pointerEvents="none"),(this.area===document?document.body:this.area).appendChild(e),e},DragSelect.prototype.start=function(){this.area.addEventListener("mousedown",this._startUp)},DragSelect.prototype._startUp=function(e){if(!this.isRightClick(e)){if(this.mouseInteraction=!0,this.selector.style.display="block",this.isMultiSelectKeyPressed(e)?this._prevSelected=this.selected.slice():this._prevSelected=[],this._getStartingPositions(e),this.checkIfInsideSelection(!0),this.selector.style.display="none",this.moveStartCallback(e),this._breaked)return!1;this.area.removeEventListener("mousedown",this._startUp),this.area.addEventListener("mousemove",this._handleMove),document.addEventListener("mouseup",this.reset)}},DragSelect.prototype.isMultiSelectKeyPressed=function(e){if(this.multiSelectKeyPressed=!1,this.multiSelectMode)this.multiSelectKeyPressed=!0;else for(var t=0;t<this.multiSelectKeys.length;t++){var s=this.multiSelectKeys[t];e[s]&&(this.multiSelectKeyPressed=!0)}return this.multiSelectKeyPressed},DragSelect.prototype._getStartingPositions=function(e){this.initialCursorPos=this.newCursorPos=this._getCursorPos(e,this.area),this.initialScroll=this.getScroll(this.area);var t={};t.x=this.initialCursorPos.x+this.initialScroll.x,t.y=this.initialCursorPos.y+this.initialScroll.y,t.w=0,t.h=0,this.updatePos(this.selector,t)},DragSelect.prototype._handleMove=function(e){var t=this.getPosition(e);if(this.moveCallback(e),this._breaked)return!1;this.selector.style.display="block",this.updatePos(this.selector,t),this.checkIfInsideSelection(),this._autoScroll(e)},DragSelect.prototype.getPosition=function(e){var t=this._getCursorPos(e,this.area),s=this.getScroll(this.area);this.newCursorPos=t;var i={x:s.x-this.initialScroll.x,y:s.y-this.initialScroll.y},o={};return t.x>this.initialCursorPos.x-i.x?(o.x=this.initialCursorPos.x+this.initialScroll.x,o.w=t.x-this.initialCursorPos.x+i.x):(o.x=t.x+s.x,o.w=this.initialCursorPos.x-t.x-i.x),t.y>this.initialCursorPos.y-i.y?(o.y=this.initialCursorPos.y+this.initialScroll.y,o.h=t.y-this.initialCursorPos.y+i.y):(o.y=t.y+s.y,o.h=this.initialCursorPos.y-t.y-i.y),o},DragSelect.prototype.checkIfInsideSelection=function(e){for(var t=!1,s=0,i=this.selectables.length;s<i;s++){var o=this.selectables[s];this.isElementTouching(o,this.selector,this.area)?(this._handleSelection(o,e),t=!0):this._handleUnselection(o,e)}return t},DragSelect.prototype._handleSelection=function(e,t){if(this.hasClass(e,this.hoverClass)&&!t)return!1;var s=this.selected.indexOf(e);s<0?this.select(e):s>-1&&this.multiSelectKeyPressed&&this.unselect(e),this.addClass(e,this.hoverClass)},DragSelect.prototype._handleUnselection=function(e,t){if(!this.hasClass(e,this.hoverClass)&&!t)return!1;var s=this.selected.indexOf(e),i=this._prevSelected.indexOf(e);s>-1&&i<0?this.unselect(e):s<0&&i>-1&&this.select(e),this.removeClass(e,this.hoverClass)},DragSelect.prototype.select=function(e){return!(this.selected.indexOf(e)>-1)&&(this.selected.push(e),this.addClass(e,this.selectedClass),this.selectCallback(e),!this._breaked&&e)},DragSelect.prototype.unselect=function(e){return!(this.selected.indexOf(e)<0)&&(this.selected.splice(this.selected.indexOf(e),1),this.removeClass(e,this.selectedClass),this.unselectCallback(e),!this._breaked&&e)},DragSelect.prototype.toggle=function(e){return this.selected.indexOf(e)>-1?this.unselect(e):this.select(e),e},DragSelect.prototype.isElementTouching=function(e,t,s){var i=this.getScroll(s),o={y:t.getBoundingClientRect().top+i.y,x:t.getBoundingClientRect().left+i.x,h:t.offsetHeight||e.getBoundingClientRect().height,w:t.offsetWidth||e.getBoundingClientRect().width},r={y:e.getBoundingClientRect().top+i.y,x:e.getBoundingClientRect().left+i.x,h:e.offsetHeight||e.getBoundingClientRect().height,w:e.offsetWidth||e.getBoundingClientRect().width};return o.x<r.x+r.w&&o.x+o.w>r.x&&o.y<r.y+r.h&&o.h+o.y>r.y},DragSelect.prototype._autoScroll=function(e){var t=this.isCursorNearEdge(e,this.area),s=this.area===document?this.area.body:this.area;"top"===t&&s.scrollTop>0?s.scrollTop-=1*this.autoScrollSpeed:"bottom"===t?s.scrollTop+=1*this.autoScrollSpeed:"left"===t&&s.scrollLeft>0?s.scrollLeft-=1*this.autoScrollSpeed:"right"===t&&(s.scrollLeft+=1*this.autoScrollSpeed)},DragSelect.prototype.isCursorNearEdge=function(e,t){var s=this._getCursorPos(e,t),i=this.getAreaRect(t),o={x:Math.max(i.width/10,30),y:Math.max(i.height/10,30)};return s.y<o.y?"top":i.height-s.y<o.y?"bottom":i.width-s.x<o.x?"right":s.x<o.x&&"left"},DragSelect.prototype.reset=function(e){if(this.previousCursorPos=this._getCursorPos(e,this.area),document.removeEventListener("mouseup",this.reset),this.area.removeEventListener("mousemove",this._handleMove),this.area.addEventListener("mousedown",this._startUp),this.callback(this.selected,e),this._breaked)return!1;this.selector.style.width="0",this.selector.style.height="0",this.selector.style.display="none",setTimeout(function(){this.mouseInteraction=!1}.bind(this),100)},DragSelect.prototype.break=function(){this._breaked=!0,setTimeout(function(){this._breaked=!1}.bind(this),100)},DragSelect.prototype.stop=function(){this.reset(),this.area.removeEventListener("mousedown",this._startUp),document.removeEventListener("mouseup",this.reset)},DragSelect.prototype.getSelection=function(){return this.selected},DragSelect.prototype.getCursorPos=function(e,t,s){if(!e)return!1;var i=t||!1!==t&&this.area,o=this._getCursorPos(e,i),r=s?{x:0,y:0}:this.getScroll(i);return{x:o.x+r.x,y:o.y+r.y}},DragSelect.prototype.addSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.select(l)}return s||this.addSelectables(i),t&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.removeSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.unselect(l)}return s&&this.removeSelectables(i),t&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.toggleSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.selected.indexOf(l)<0?this.addSelection(l,t,s):this.removeSelection(l,t,s)}return this.selected},DragSelect.prototype.setSelection=function(e,t,s){return this.clearSelection(),this.addSelection(e,t,s),this.selected},DragSelect.prototype.clearSelection=function(e){for(var t=this.selected.slice(),s=0,i=t.length;s<i;s++){var o=t[s];this.unselect(o)}return e&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.addSelectables=function(e,t){var s=this.toArray(e);return this._handleSelectables(s,!1,t),e},DragSelect.prototype.getSelectables=function(){return this.selectables},DragSelect.prototype.setSelectables=function(e,t,s){return this.removeSelectables(this.getSelectables(),t),this.addSelectables(e,s)},DragSelect.prototype.removeSelectables=function(e,t){var s=this.toArray(e);return this._handleSelectables(s,!0,t),e},DragSelect.prototype.isRightClick=function(e){if(!e)return!1;var t=!1;return"which"in e?t=3===e.which:"button"in e&&(t=2===e.button),t},DragSelect.prototype.addClass=function(e,t){if(e.classList)return e.classList.add(t);var s=e.getAttribute("class")||"";return-1!==s.indexOf(t)?e:(""!==s&&(t=" "+t),e.setAttribute("class",s+t),e)},DragSelect.prototype.removeClass=function(e,t){if(e.classList)return e.classList.remove(t);var s=e.getAttribute("class")||"",i=new RegExp(t+"\\b","g");return s=s.replace(i,""),e.setAttribute("class",s),e},DragSelect.prototype.hasClass=function(e,t){return e.classList?e.classList.contains(t):(e.getAttribute("class")||"").indexOf(t)>-1},DragSelect.prototype.toArray=function(e){if(!e)return!1;if(!e.length&&this.isElement(e))return[e];for(var t=[],s=e.length-1;s>=0;s--)t[s]=e[s];return t},DragSelect.prototype.isElement=function(e){try{return e instanceof HTMLElement||e instanceof SVGElement}catch(t){return"object"==typeof e&&1===e.nodeType&&"object"==typeof e.style&&"object"==typeof e.ownerDocument}},DragSelect.prototype._getCursorPos=function(e,t){if(!e)return{x:0,y:0};var s={x:e.pageX||e.clientX,y:e.pageY||e.clientY},i=this.getAreaRect(t||document),o=this.getScroll();return{x:s.x-i.left-o.x,y:s.y-i.top-o.y}},DragSelect.prototype.getInitialCursorPosition=function(){return this.initialCursorPos},DragSelect.prototype.getCurrentCursorPosition=function(){return this.newCursorPos},DragSelect.prototype.getPreviousCursorPosition=function(){return this.previousCursorPos},DragSelect.prototype.getCursorPositionDifference=function(e){var t=this.getCurrentCursorPosition(),s=e?this.getPreviousCursorPosition():this.getInitialCursorPosition();return{x:t.x-s.x,y:t.y-s.y}},DragSelect.prototype.getScroll=function(e){var t={top:document.body.scrollTop>0?document.body.scrollTop:document.documentElement.scrollTop,left:document.body.scrollLeft>0?document.body.scrollLeft:document.documentElement.scrollLeft};return{y:e&&e.scrollTop>=0?e.scrollTop:t.top,x:e&&e.scrollLeft>=0?e.scrollLeft:t.left}},DragSelect.prototype.getAreaRect=function(e){if(e===document){var t={y:e.documentElement.clientHeight>0?e.documentElement.clientHeight:window.innerHeight,x:e.documentElement.clientWidth>0?e.documentElement.clientWidth:window.innerWidth};return{top:0,left:0,bottom:0,right:0,width:t.x,height:t.y}}return{top:e.getBoundingClientRect().top,left:e.getBoundingClientRect().left,bottom:e.getBoundingClientRect().bottom,right:e.getBoundingClientRect().right,width:e.offsetWidth,height:e.offsetHeight}},DragSelect.prototype.updatePos=function(e,t){return e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e},"undefined"!=typeof module&&null!==module?module.exports=DragSelect:"undefined"!=typeof define&&"function"==typeof define&&define?define(function(){return DragSelect}):window.DragSelect=DragSelect;
function DragSelect(e){this.multiSelectKeyPressed,this.initialCursorPos={x:0,y:0},this.newCursorPos={x:0,y:0},this.previousCursorPos={x:0,y:0},this.initialScroll,this.selected=[],this._prevSelected=[],this._createBindings(),this._setupOptions(e),this.start()}DragSelect.prototype._createBindings=function(){this._startUp=this._startUp.bind(this),this._handleMove=this._handleMove.bind(this),this.reset=this.reset.bind(this),this._onClick=this._onClick.bind(this)},DragSelect.prototype._setupOptions=function(e){if(this.selectedClass=e.selectedClass||"ds-selected",this.hoverClass=e.hoverClass||"ds-hover",this.selectorClass=e.selectorClass||"ds-selector",this.selectableClass=e.selectableClass||"ds-selectable",this.selectables=[],this._handleSelectables(this.toArray(e.selectables)),this.multiSelectKeys=e.multiSelectKeys||["ctrlKey","shiftKey","metaKey"],this.multiSelectMode=e.multiSelectMode||!1,this.autoScrollSpeed=0===e.autoScrollSpeed?0:e.autoScrollSpeed||1,this.selectCallback=e.onElementSelect||function(){},this.unselectCallback=e.onElementUnselect||function(){},this.onDragStartBegin=e.onDragStartBegin||function(){},this.moveStartCallback=e.onDragStart||function(){},this.moveCallback=e.onDragMove||function(){},this.callback=e.callback||function(){},this.area=e.area||document,this.customStyles=e.customStyles,this.area!==document){var t=getComputedStyle(this.area);"absolute"===t.position||"relative"===t.position||"fixed"===t.position||(this.area.style.position="relative")}this.selector=e.selector||this._createSelector(),this.addClass(this.selector,this.selectorClass)},DragSelect.prototype._handleSelectables=function(e,t,s){for(var i=0;i<e.length;i++){var o=e[i],r=this.selectables.indexOf(o);r<0&&!t?(this.addClass(o,this.selectableClass),o.addEventListener("click",this._onClick),this.selectables.push(o),s&&this.selected.indexOf(o)<0&&(this.addClass(o,this.selectedClass),this.selected.push(o))):r>-1&&t&&(this.removeClass(o,this.hoverClass),this.removeClass(o,this.selectableClass),o.removeEventListener("click",this._onClick),this.selectables.splice(r,1),s&&this.selected.indexOf(o)>-1&&(this.removeClass(o,this.selectedClass),this.selected.splice(this.selected.indexOf(o),1)))}},DragSelect.prototype._onClick=function(e){if(!this.mouseInteraction&&!this.isRightClick(e)){var t=e.target;this.isMultiSelectKeyPressed(e)?this._prevSelected=this.selected.slice():this._prevSelected=[],this.checkIfInsideSelection(!0),this.selectables.indexOf(t)>-1&&this.toggle(t),this.reset()}},DragSelect.prototype._createSelector=function(){var e=document.createElement("div");return e.style.position="absolute",this.customStyles||(e.style.background="rgba(0, 0, 255, 0.1)",e.style.border="1px solid rgba(0, 0, 255, 0.45)",e.style.display="none",e.style.pointerEvents="none"),(this.area===document?document.body:this.area).appendChild(e),e},DragSelect.prototype.start=function(){this.area.addEventListener("mousedown",this._startUp)},DragSelect.prototype._startUp=function(e){if(this.onDragStartBegin(e),this._breaked)return!1;if(!this.isRightClick(e)){if(this.mouseInteraction=!0,this.selector.style.display="block",this.isMultiSelectKeyPressed(e)?this._prevSelected=this.selected.slice():this._prevSelected=[],this._getStartingPositions(e),this.checkIfInsideSelection(!0),this.selector.style.display="none",this.moveStartCallback(e),this._breaked)return!1;this.area.removeEventListener("mousedown",this._startUp),this.area.addEventListener("mousemove",this._handleMove),document.addEventListener("mouseup",this.reset)}},DragSelect.prototype.isMultiSelectKeyPressed=function(e){if(this.multiSelectKeyPressed=!1,this.multiSelectMode)this.multiSelectKeyPressed=!0;else for(var t=0;t<this.multiSelectKeys.length;t++){var s=this.multiSelectKeys[t];e[s]&&(this.multiSelectKeyPressed=!0)}return this.multiSelectKeyPressed},DragSelect.prototype._getStartingPositions=function(e){this.initialCursorPos=this.newCursorPos=this._getCursorPos(e,this.area),this.initialScroll=this.getScroll(this.area);var t={};t.x=this.initialCursorPos.x+this.initialScroll.x,t.y=this.initialCursorPos.y+this.initialScroll.y,t.w=0,t.h=0,this.updatePos(this.selector,t)},DragSelect.prototype._handleMove=function(e){var t=this.getPosition(e);if(this.moveCallback(e),this._breaked)return!1;this.selector.style.display="block",this.updatePos(this.selector,t),this.checkIfInsideSelection(),this._autoScroll(e)},DragSelect.prototype.getPosition=function(e){var t=this._getCursorPos(e,this.area),s=this.getScroll(this.area);this.newCursorPos=t;var i={x:s.x-this.initialScroll.x,y:s.y-this.initialScroll.y},o={};return t.x>this.initialCursorPos.x-i.x?(o.x=this.initialCursorPos.x+this.initialScroll.x,o.w=t.x-this.initialCursorPos.x+i.x):(o.x=t.x+s.x,o.w=this.initialCursorPos.x-t.x-i.x),t.y>this.initialCursorPos.y-i.y?(o.y=this.initialCursorPos.y+this.initialScroll.y,o.h=t.y-this.initialCursorPos.y+i.y):(o.y=t.y+s.y,o.h=this.initialCursorPos.y-t.y-i.y),o},DragSelect.prototype.checkIfInsideSelection=function(e){for(var t=!1,s=0,i=this.selectables.length;s<i;s++){var o=this.selectables[s],r=this.getScroll(this.area),l={y:this.selector.getBoundingClientRect().top+r.y,x:this.selector.getBoundingClientRect().left+r.x,h:this.selector.offsetHeight,w:this.selector.offsetWidth};this._isElementTouching(o,l,r)?(this._handleSelection(o,e),t=!0):this._handleUnselection(o,e)}return t},DragSelect.prototype._handleSelection=function(e,t){if(this.hasClass(e,this.hoverClass)&&!t)return!1;var s=this.selected.indexOf(e);s<0?this.select(e):s>-1&&this.multiSelectKeyPressed&&this.unselect(e),this.addClass(e,this.hoverClass)},DragSelect.prototype._handleUnselection=function(e,t){if(!this.hasClass(e,this.hoverClass)&&!t)return!1;var s=this.selected.indexOf(e),i=this._prevSelected.indexOf(e);s>-1&&i<0?this.unselect(e):s<0&&i>-1&&this.select(e),this.removeClass(e,this.hoverClass)},DragSelect.prototype.select=function(e){return!(this.selected.indexOf(e)>-1)&&(this.selected.push(e),this.addClass(e,this.selectedClass),this.selectCallback(e),!this._breaked&&e)},DragSelect.prototype.unselect=function(e){return!(this.selected.indexOf(e)<0)&&(this.selected.splice(this.selected.indexOf(e),1),this.removeClass(e,this.selectedClass),this.unselectCallback(e),!this._breaked&&e)},DragSelect.prototype.toggle=function(e){return this.selected.indexOf(e)>-1?this.unselect(e):this.select(e),e},DragSelect.prototype._isElementTouching=function(e,t,s){var i={y:e.getBoundingClientRect().top+s.y,x:e.getBoundingClientRect().left+s.x,h:e.offsetHeight||e.getBoundingClientRect().height,w:e.offsetWidth||e.getBoundingClientRect().width};return t.x<i.x+i.w&&t.x+t.w>i.x&&t.y<i.y+i.h&&t.h+t.y>i.y},DragSelect.prototype._autoScroll=function(e){var t=this.isCursorNearEdge(e,this.area),s=this.area===document?document.documentElement||document.body:this.area;"top"===t&&s.scrollTop>0?s.scrollTop-=1*this.autoScrollSpeed:"bottom"===t?s.scrollTop+=1*this.autoScrollSpeed:"left"===t&&s.scrollLeft>0?s.scrollLeft-=1*this.autoScrollSpeed:"right"===t&&(s.scrollLeft+=1*this.autoScrollSpeed)},DragSelect.prototype.isCursorNearEdge=function(e,t){var s=this._getCursorPos(e,t),i=this.getAreaRect(t),o={x:Math.max(i.width/10,30),y:Math.max(i.height/10,30)};return s.y<o.y?"top":i.height-s.y<o.y?"bottom":i.width-s.x<o.x?"right":s.x<o.x&&"left"},DragSelect.prototype.reset=function(e){if(this.previousCursorPos=this._getCursorPos(e,this.area),document.removeEventListener("mouseup",this.reset),this.area.removeEventListener("mousemove",this._handleMove),this.area.addEventListener("mousedown",this._startUp),this.callback(this.selected,e),this._breaked)return!1;this.selector.style.width="0",this.selector.style.height="0",this.selector.style.display="none",setTimeout(function(){this.mouseInteraction=!1}.bind(this),100)},DragSelect.prototype.break=function(){this._breaked=!0,setTimeout(function(){this._breaked=!1}.bind(this),100)},DragSelect.prototype.stop=function(){this.reset(),this.area.removeEventListener("mousedown",this._startUp),document.removeEventListener("mouseup",this.reset)},DragSelect.prototype.getSelection=function(){return this.selected},DragSelect.prototype.getCursorPos=function(e,t,s){if(!e)return!1;var i=t||!1!==t&&this.area,o=this._getCursorPos(e,i),r=s?{x:0,y:0}:this.getScroll(i);return{x:o.x+r.x,y:o.y+r.y}},DragSelect.prototype.addSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.select(l)}return s||this.addSelectables(i),t&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.removeSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.unselect(l)}return s&&this.removeSelectables(i),t&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.toggleSelection=function(e,t,s){for(var i=this.toArray(e),o=0,r=i.length;o<r;o++){var l=i[o];this.selected.indexOf(l)<0?this.addSelection(l,t,s):this.removeSelection(l,t,s)}return this.selected},DragSelect.prototype.setSelection=function(e,t,s){return this.clearSelection(),this.addSelection(e,t,s),this.selected},DragSelect.prototype.clearSelection=function(e){for(var t=this.selected.slice(),s=0,i=t.length;s<i;s++){var o=t[s];this.unselect(o)}return e&&this.callback(this.selected,!1),this.selected},DragSelect.prototype.addSelectables=function(e,t){var s=this.toArray(e);return this._handleSelectables(s,!1,t),e},DragSelect.prototype.getSelectables=function(){return this.selectables},DragSelect.prototype.setSelectables=function(e,t,s){return this.removeSelectables(this.getSelectables(),t),this.addSelectables(e,s)},DragSelect.prototype.removeSelectables=function(e,t){var s=this.toArray(e);return this._handleSelectables(s,!0,t),e},DragSelect.prototype.isRightClick=function(e){if(!e)return!1;var t=!1;return"which"in e?t=3===e.which:"button"in e&&(t=2===e.button),t},DragSelect.prototype.addClass=function(e,t){if(e.classList)return e.classList.add(t);var s=e.getAttribute("class")||"";return-1!==s.indexOf(t)?e:(""!==s&&(t=" "+t),e.setAttribute("class",s+t),e)},DragSelect.prototype.removeClass=function(e,t){if(e.classList)return e.classList.remove(t);var s=e.getAttribute("class")||"",i=new RegExp(t+"\\b","g");return s=s.replace(i,""),e.setAttribute("class",s),e},DragSelect.prototype.hasClass=function(e,t){return e.classList?e.classList.contains(t):(e.getAttribute("class")||"").indexOf(t)>-1},DragSelect.prototype.toArray=function(e){if(!e)return!1;if(!e.length&&this.isElement(e))return[e];for(var t=[],s=e.length-1;s>=0;s--)t[s]=e[s];return t},DragSelect.prototype.isElement=function(e){try{return e instanceof HTMLElement||e instanceof SVGElement}catch(t){return"object"==typeof e&&1===e.nodeType&&"object"==typeof e.style&&"object"==typeof e.ownerDocument}},DragSelect.prototype._getCursorPos=function(e,t){if(!e)return{x:0,y:0};var s={x:e.pageX||e.clientX,y:e.pageY||e.clientY},i=this.getAreaRect(t||document),o=this.getScroll();return{x:s.x-i.left-o.x,y:s.y-i.top-o.y}},DragSelect.prototype.getInitialCursorPosition=function(){return this.initialCursorPos},DragSelect.prototype.getCurrentCursorPosition=function(){return this.newCursorPos},DragSelect.prototype.getPreviousCursorPosition=function(){return this.previousCursorPos},DragSelect.prototype.getCursorPositionDifference=function(e){var t=this.getCurrentCursorPosition(),s=e?this.getPreviousCursorPosition():this.getInitialCursorPosition();return{x:t.x-s.x,y:t.y-s.y}},DragSelect.prototype.getScroll=function(e){var t={top:document.body.scrollTop>0?document.body.scrollTop:document.documentElement.scrollTop,left:document.body.scrollLeft>0?document.body.scrollLeft:document.documentElement.scrollLeft};return{y:e&&e.scrollTop>=0?e.scrollTop:t.top,x:e&&e.scrollLeft>=0?e.scrollLeft:t.left}},DragSelect.prototype.getAreaRect=function(e){if(e===document){var t={y:e.documentElement.clientHeight>0?e.documentElement.clientHeight:window.innerHeight,x:e.documentElement.clientWidth>0?e.documentElement.clientWidth:window.innerWidth};return{top:0,left:0,bottom:0,right:0,width:t.x,height:t.y}}return{top:e.getBoundingClientRect().top,left:e.getBoundingClientRect().left,bottom:e.getBoundingClientRect().bottom,right:e.getBoundingClientRect().right,width:e.offsetWidth,height:e.offsetHeight}},DragSelect.prototype.updatePos=function(e,t){return e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e},"undefined"!=typeof module&&null!==module?module.exports=DragSelect:"undefined"!=typeof define&&"function"==typeof define&&define?define(function(){return DragSelect}):window.DragSelect=DragSelect;
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var htmlhint = require('gulp-htmlhint');
var htmlmin = require('gulp-htmlmin');

@@ -10,6 +8,5 @@ var autoprefixer = require('gulp-autoprefixer');

gulp.task('js', function () {
gulp.src('./src/DragSelect.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
gulp.task('js', function() {
gulp
.src('./src/DragSelect.js')
.pipe(gulp.dest('./dist/'))

@@ -21,4 +18,5 @@ .pipe(uglify())

gulp.task('css', function () {
gulp.src('./src/example.css')
gulp.task('css', function() {
gulp
.src('./src/example.css')
.pipe(autoprefixer())

@@ -29,14 +27,13 @@ .pipe(csso())

gulp.task('html', function () {
gulp.src('./src/index.html')
.pipe(htmlhint())
.pipe(htmlmin({collapseWhitespace: true}))
gulp.task('html', function() {
gulp
.src('./src/index.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('./dist/'));
});
gulp.task('quicktest', function () {
gulp.src('./src/quicktest.html')
.pipe(gulp.dest('./dist/'));
gulp.task('quicktest', function() {
gulp.src('./src/quicktest.html').pipe(gulp.dest('./dist/'));
});
gulp.task('default', ['js', 'html', 'css', 'quicktest']);
{
"name": "dragselect",
"version": "1.8.1",
"version": "1.9.0",
"description": "easy javascript drag select functionality for your projects",

@@ -21,3 +21,2 @@ "main": "./dist/ds.min.js",

"gulp-csso": "^2.0.0",
"gulp-htmlhint": "^0.3.1",
"gulp-htmlmin": "^3.0.0",

@@ -24,0 +23,0 @@ "gulp-jshint": "^2.0.4",

@@ -86,3 +86,3 @@ ```

multiSelectMode: false, // If set to true, the multiselection behavior will be turned on by default without the need of modifier keys. Default: false
autoScrollSpeed: 3, // Speed in which the area scrolls while selecting (if available). Unit is pixel per movement. Set to 0.0001 to disable autoscrolling. Default = 1
autoScrollSpeed: 3, // Speed in which the area scrolls while selecting (if available). Unit is pixel per movement. Set to 0 to disable autoscrolling. Default = 1
onDragStart: function(element) {}, // fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, befor the setup of event listeners.

@@ -132,2 +132,3 @@ onDragMove: function(element) {}, // fired when the user drags. This callback gets the event object. Executed before DragSelect function code ran, after getting the current mouse position.

|selectableClass |string |OPTIONAL. The class name assigned to the elements that can be selected. Default = [see classes](#classes) |
|onDragStartBegin |function |OPTIONAL. Fired when the user clicks in the area. This callback gets the event object. Executed **before** DragSelect function code runs |
|onDragStart |function |OPTIONAL. Fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, befor the setup of event listeners |

@@ -134,0 +135,0 @@ |onDragMove |function |OPTIONAL. Fired when the user drags. This callback gets the event object. Executed before DragSelect function code ran, after getting the current mouse position |

@@ -1,2 +0,2 @@

// v 1.8.1
// v 1.9.0
/*

@@ -38,3 +38,4 @@ ____ _____ __ __

** @selectableClass string the class assigned to the elements that can be selected
** @onDragStart function It is fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, befor the setup of event listeners.
** @onDragStartBegin function Is fired when the user clicks in the area. This callback gets the event object. Executed *before* DragSelect function code ran.
** @onDragStart function It is fired when the user clicks in the area. This callback gets the event object. Executed after DragSelect function code ran, before the setup of event listeners.
** @onDragMove function It is fired when the user drags. This callback gets the event object. Executed before DragSelect function code ran, after getting the current mouse position.

@@ -100,20 +101,18 @@ ** @onElementSelect function It is fired every time an element is selected. This callback gets a property which is the just selected node

* DragSelect Class.
*
*
* @constructor
* @param {Object} options - The options object.
*/
function DragSelect( options ) {
function DragSelect(options) {
this.multiSelectKeyPressed;
this.initialCursorPos = {x: 0, y: 0};
this.newCursorPos = {x: 0, y: 0};
this.previousCursorPos = {x: 0, y: 0};
this.initialCursorPos = { x: 0, y: 0 };
this.newCursorPos = { x: 0, y: 0 };
this.previousCursorPos = { x: 0, y: 0 };
this.initialScroll;
this.selected = [];
this._prevSelected = []; // memory to fix #9
this._prevSelected = []; // memory to fix #9
this._createBindings();
this._setupOptions( options );
this._setupOptions(options);
this.start();
}

@@ -125,3 +124,2 @@

DragSelect.prototype._createBindings = function() {
this._startUp = this._startUp.bind(this);

@@ -131,3 +129,2 @@ this._handleMove = this._handleMove.bind(this);

this._onClick = this._onClick.bind(this);
};

@@ -138,4 +135,3 @@

*/
DragSelect.prototype._setupOptions = function( options ) {
DragSelect.prototype._setupOptions = function(options) {
this.selectedClass = options.selectedClass || 'ds-selected';

@@ -147,9 +143,14 @@ this.hoverClass = options.hoverClass || 'ds-hover';

this.selectables = [];
this._handleSelectables( this.toArray( options.selectables ) );
this._handleSelectables(this.toArray(options.selectables));
this.multiSelectKeys = options.multiSelectKeys || ['ctrlKey', 'shiftKey', 'metaKey'];
this.multiSelectKeys = options.multiSelectKeys || [
'ctrlKey',
'shiftKey',
'metaKey'
];
this.multiSelectMode = options.multiSelectMode || false;
this.autoScrollSpeed = options.autoScrollSpeed || 1;
this.autoScrollSpeed = options.autoScrollSpeed === 0 ? 0 : options.autoScrollSpeed || 1;
this.selectCallback = options.onElementSelect || function() {};
this.unselectCallback = options.onElementUnselect || function() {};
this.onDragStartBegin = options.onDragStartBegin || function() {};
this.moveStartCallback = options.onDragStart || function() {};

@@ -162,6 +163,11 @@ this.moveCallback = options.onDragMove || function() {};

// Area has to have a special position attribute for calculations
if( this.area !== document ) {
var computedArea = getComputedStyle( this.area );
var isPositioned = computedArea.position === 'absolute' || computedArea.position === 'relative' || computedArea.position === 'fixed';
if( !isPositioned ) { this.area.style.position = 'relative'; }
if (this.area !== document) {
var computedArea = getComputedStyle(this.area);
var isPositioned =
computedArea.position === 'absolute' ||
computedArea.position === 'relative' ||
computedArea.position === 'fixed';
if (!isPositioned) {
this.area.style.position = 'relative';
}
}

@@ -171,4 +177,3 @@

this.selector = options.selector || this._createSelector();
this.addClass( this.selector, this.selectorClass );
this.addClass(this.selector, this.selectorClass);
};

@@ -178,3 +183,3 @@

* Add/Remove Selectables also handles css classes and event listeners.
*
*
* @param {Object} selectables - selectable elements.

@@ -184,38 +189,38 @@ * @param {Boolean} remove - if elements should be removed.

*/
DragSelect.prototype._handleSelectables = function( selectables, remove, fromSelection ) {
for ( var index = 0; index < selectables.length; index++ ) {
DragSelect.prototype._handleSelectables = function(
selectables,
remove,
fromSelection
) {
for (var index = 0; index < selectables.length; index++) {
var selectable = selectables[index];
var indexOf = this.selectables.indexOf( selectable );
var indexOf = this.selectables.indexOf(selectable);
if( indexOf < 0 && !remove ) { // add
this.addClass( selectable, this.selectableClass );
selectable.addEventListener( 'click', this._onClick );
this.selectables.push( selectable );
if (indexOf < 0 && !remove) {
// add
this.addClass(selectable, this.selectableClass);
selectable.addEventListener('click', this._onClick);
this.selectables.push(selectable);
// also add to current selection
if( fromSelection && this.selected.indexOf( selectable ) < 0 ) {
this.addClass( selectable, this.selectedClass );
this.selected.push( selectable );
if (fromSelection && this.selected.indexOf(selectable) < 0) {
this.addClass(selectable, this.selectedClass);
this.selected.push(selectable);
}
} else if (indexOf > -1 && remove) {
// remove
}
this.removeClass(selectable, this.hoverClass);
this.removeClass(selectable, this.selectableClass);
selectable.removeEventListener('click', this._onClick);
this.selectables.splice(indexOf, 1);
else if( indexOf > -1 && remove ) { // remove
this.removeClass( selectable, this.hoverClass );
this.removeClass( selectable, this.selectableClass );
selectable.removeEventListener( 'click', this._onClick );
this.selectables.splice( indexOf, 1 );
// also remove from current selection
if( fromSelection && this.selected.indexOf( selectable ) > -1 ) {
this.removeClass( selectable, this.selectedClass );
this.selected.splice( this.selected.indexOf( selectable ), 1 );
if (fromSelection && this.selected.indexOf(selectable) > -1) {
this.removeClass(selectable, this.selectedClass);
this.selected.splice(this.selected.indexOf(selectable), 1);
}
}
}
};

@@ -225,26 +230,35 @@

* Triggers when a node is actively selected.
*
*
* This might be an "onClick" method but it also triggers when
* <button> nodes are pressed via the keyboard.
* Making DragSelect accessible for everyone!
*
*
* @param {Object} selectables - selectable elements.
* @param {Boolean} remove - if elements were removed.
*/
DragSelect.prototype._onClick = function( event ) {
DragSelect.prototype._onClick = function(event) {
if( this.mouseInteraction ) { return; } // fix firefox doubleclick issue
if( this.isRightClick( event ) ) { return; }
if (this.mouseInteraction) {
return;
} // fix firefox doubleclick issue
if (this.isRightClick(event)) {
return;
}
var node = event.target;
if(this.isMultiSelectKeyPressed( event )) { this._prevSelected = this.selected.slice(); } // #9
else { this._prevSelected = []; } // #9
if (this.isMultiSelectKeyPressed(event)) {
this._prevSelected = this.selected.slice();
} // #9
else {
this._prevSelected = [];
} // #9
this.checkIfInsideSelection( true ); // reset selection if no multiselectionkeypressed
this.checkIfInsideSelection(true); // reset selection if no multiselectionkeypressed
if( this.selectables.indexOf( node ) > -1 ) { this.toggle( node ); }
if (this.selectables.indexOf(node) > -1) {
this.toggle(node);
}
this.reset();
};

@@ -254,22 +268,20 @@

* Create the selector node when not provided by options object.
*
*
* @return {Node}
*/
DragSelect.prototype._createSelector = function() {
var selector = document.createElement('div');
var selector = document.createElement( 'div' );
selector.style.position = 'absolute';
if( !this.customStyles ) {
if (!this.customStyles) {
selector.style.background = 'rgba(0, 0, 255, 0.1)';
selector.style.border = '1px solid rgba(0, 0, 255, 0.45)';
selector.style.display = 'none';
selector.style.pointerEvents = 'none'; // fix for issue #8 (ie11+)
selector.style.pointerEvents = 'none'; // fix for issue #8 (ie11+)
}
var _area = this.area === document ? document.body : this.area;
_area.appendChild( selector );
_area.appendChild(selector);
return selector;
};

@@ -284,5 +296,3 @@

DragSelect.prototype.start = function() {
this.area.addEventListener( 'mousedown', this._startUp );
this.area.addEventListener('mousedown', this._startUp);
};

@@ -292,30 +302,39 @@

* Startup when the area is clicked.
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._startUp = function( event ) {
DragSelect.prototype._startUp = function(event) {
if( this.isRightClick( event ) ) { return; }
// callback
this.onDragStartBegin(event);
if (this._breaked) { return false; }
if (this.isRightClick(event)) {
return;
}
this.mouseInteraction = true;
this.selector.style.display = 'block';
if(this.isMultiSelectKeyPressed( event )) { this._prevSelected = this.selected.slice(); } // #9
else { this._prevSelected = []; } // #9
if (this.isMultiSelectKeyPressed(event)) {
this._prevSelected = this.selected.slice();
} // #9
else {
this._prevSelected = [];
} // #9
// move element on location
this._getStartingPositions( event );
this.checkIfInsideSelection( true );
this._getStartingPositions(event);
this.checkIfInsideSelection(true);
this.selector.style.display = 'none'; // hidden unless moved, fix for issue #8
this.selector.style.display = 'none'; // hidden unless moved, fix for issue #8
// callback
this.moveStartCallback( event );
if( this._breaked ) { return false; }
this.moveStartCallback(event);
if (this._breaked) { return false; }
// event listeners
this.area.removeEventListener( 'mousedown', this._startUp );
this.area.addEventListener( 'mousemove', this._handleMove );
document.addEventListener( 'mouseup', this.reset );
this.area.removeEventListener('mousedown', this._startUp);
this.area.addEventListener('mousemove', this._handleMove);
document.addEventListener('mouseup', this.reset);
};

@@ -325,16 +344,17 @@

* Check if some multiselection modifier key is pressed
*
*
* @param {Object} event - The event object.
* @return {Boolean} this.isMultiSelectKeyPressed
*/
DragSelect.prototype.isMultiSelectKeyPressed = function( event ) {
DragSelect.prototype.isMultiSelectKeyPressed = function(event) {
this.multiSelectKeyPressed = false;
if (this.multiSelectMode){
if (this.multiSelectMode) {
this.multiSelectKeyPressed = true;
} else {
for ( var index = 0; index < this.multiSelectKeys.length; index++ ) {
for (var index = 0; index < this.multiSelectKeys.length; index++) {
var mKey = this.multiSelectKeys[index];
if( event[mKey] ) { this.multiSelectKeyPressed = true; }
if (event[mKey]) {
this.multiSelectKeyPressed = true;
}
}

@@ -344,3 +364,2 @@ }

return this.multiSelectKeyPressed;
};

@@ -350,10 +369,12 @@

* Grabs the starting position of all needed elements
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._getStartingPositions = function( event ) {
DragSelect.prototype._getStartingPositions = function(event) {
this.initialCursorPos = this.newCursorPos = this._getCursorPos(
event,
this.area
);
this.initialScroll = this.getScroll(this.area);
this.initialCursorPos = this.newCursorPos = this._getCursorPos( event, this.area );
this.initialScroll = this.getScroll( this.area );
var selectorPos = {};

@@ -364,7 +385,5 @@ selectorPos.x = this.initialCursorPos.x + this.initialScroll.x;

selectorPos.h = 0;
this.updatePos( this.selector, selectorPos );
this.updatePos(this.selector, selectorPos);
};
// Movements/Sizing of selection

@@ -375,22 +394,22 @@ //////////////////////////////////////////////////////////////////////////////////////

* Handles what happens while the mouse is moved
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype._handleMove = function( event ) {
DragSelect.prototype._handleMove = function(event) {
var selectorPos = this.getPosition(event);
var selectorPos = this.getPosition( event );
// callback
this.moveCallback( event );
if( this._breaked ) { return false; }
this.moveCallback(event);
if (this._breaked) {
return false;
}
this.selector.style.display = 'block'; // hidden unless moved, fix for issue #8
this.selector.style.display = 'block'; // hidden unless moved, fix for issue #8
// move element on location
this.updatePos( this.selector, selectorPos );
this.updatePos(this.selector, selectorPos);
this.checkIfInsideSelection();
// scroll area if area is scrollable
this._autoScroll( event );
this._autoScroll(event);
};

@@ -400,10 +419,9 @@

* Calculates and returns the exact x,y w,h positions of the selector element
*
*
* @param {Object} event - The event object.
*/
DragSelect.prototype.getPosition = function( event ) {
DragSelect.prototype.getPosition = function(event) {
var cursorPosNew = this._getCursorPos(event, this.area);
var scrollNew = this.getScroll(this.area);
var cursorPosNew = this._getCursorPos( event, this.area );
var scrollNew = this.getScroll( this.area );
// save for later retrieval

@@ -429,3 +447,3 @@ this.newCursorPos = cursorPosNew;

* by +10px width to fake a negative sizing.
*
*
* One solution to this problem is using css-transforms scale() with

@@ -435,3 +453,3 @@ * transform-origin of top left. BUT we can’t use this since it will size

* get inanely huge. Also transforms are not widely supported in IE.
*
*
* Example #1:

@@ -449,3 +467,3 @@ * Unfortunately, things get even more complicated when we are inside a scrollable

* 3. selectorPos.w = cursorPosNew.x (5) - initialCursorPos.x (0) + scrollAmount.x (10) === 15;
*
*
* let’s say after that movement we now scroll 20px to the left and move our cursor by 30px to the left:

@@ -455,7 +473,7 @@ * 1b. cursorPosNew.x (-30) > initialCursorPos.x (0) - scrollAmount.x (-20) === -30 > -20 === false;

* === -50; // move left position to cursor (for more info see Problem #1)
* 3b. selectorPos.w = initialCursorPos.x (0) - cursorPosNew.x (-30) - scrollAmount.x (-20)
* 3b. selectorPos.w = initialCursorPos.x (0) - cursorPosNew.x (-30) - scrollAmount.x (-20)
* === 0--30--20 === 0+30+20 === 50; // scale width to original left position (for more info see Problem #1)
*
*
* same thing has to be done for top/bottom
*
*
* I hope that makes sence, try stuff out and play around with variables to get a hang of it.

@@ -466,16 +484,18 @@ */

// right
if( cursorPosNew.x > this.initialCursorPos.x - scrollAmount.x ) { // 1.
selectorPos.x = this.initialCursorPos.x + this.initialScroll.x; // 2.
selectorPos.w = cursorPosNew.x - this.initialCursorPos.x + scrollAmount.x; // 3.
// left
} else { // 1b.
selectorPos.x = cursorPosNew.x + scrollNew.x; // 2b.
selectorPos.w = this.initialCursorPos.x - cursorPosNew.x - scrollAmount.x; // 3b.
if (cursorPosNew.x > this.initialCursorPos.x - scrollAmount.x) {
// 1.
selectorPos.x = this.initialCursorPos.x + this.initialScroll.x; // 2.
selectorPos.w = cursorPosNew.x - this.initialCursorPos.x + scrollAmount.x; // 3.
// left
} else {
// 1b.
selectorPos.x = cursorPosNew.x + scrollNew.x; // 2b.
selectorPos.w = this.initialCursorPos.x - cursorPosNew.x - scrollAmount.x; // 3b.
}
// bottom
if( cursorPosNew.y > this.initialCursorPos.y - scrollAmount.y ) {
if (cursorPosNew.y > this.initialCursorPos.y - scrollAmount.y) {
selectorPos.y = this.initialCursorPos.y + this.initialScroll.y;
selectorPos.h = cursorPosNew.y - this.initialCursorPos.y + scrollAmount.y;
// top
// top
} else {

@@ -487,6 +507,4 @@ selectorPos.y = cursorPosNew.y + scrollNew.y;

return selectorPos;
};
// Colision detection

@@ -497,20 +515,24 @@ //////////////////////////////////////////////////////////////////////////////////////

* Checks if element is inside selection and takes action based on that
*
*
* force handles first clicks and accessibility. Here is user is clicking directly onto
* some element at start, (contrary to later hovers) we can assume that he
* really wants to select/deselect that item.
*
*
* @param {Boolean} force – forces through.
*
* @return {Boolean}
*/
DragSelect.prototype.checkIfInsideSelection = function( force ) {
DragSelect.prototype.checkIfInsideSelection = function(force) {
var anyInside = false;
for( var i = 0, il = this.selectables.length; i < il; i++ ) {
var selectable = this.selectables[i];
if( this.isElementTouching( selectable, this.selector, this.area ) ) {
var scroll = this.getScroll(this.area);
var selectionRect = {
y: this.selector.getBoundingClientRect().top + scroll.y,
x: this.selector.getBoundingClientRect().left + scroll.x,
h: this.selector.offsetHeight,
w: this.selector.offsetWidth
};
if( this._isElementTouching( selectable, selectionRect, scroll ) ) {
this._handleSelection( selectable, force );

@@ -521,7 +543,4 @@ anyInside = true;

}
}
return anyInside;
};

@@ -531,19 +550,19 @@

* Logic when an item is selected
*
*
* @param {Node} item – selected item.
* @param {Boolean} force – forces through.
*/
DragSelect.prototype._handleSelection = function( item, force ) {
DragSelect.prototype._handleSelection = function(item, force) {
if (this.hasClass(item, this.hoverClass) && !force) {
return false;
}
var posInSelectedArray = this.selected.indexOf(item);
if( this.hasClass( item, this.hoverClass ) && !force ) { return false; }
var posInSelectedArray = this.selected.indexOf( item );
if( posInSelectedArray < 0 ) {
this.select( item );
} else if( posInSelectedArray > -1 && this.multiSelectKeyPressed ) {
this.unselect( item );
if (posInSelectedArray < 0) {
this.select(item);
} else if (posInSelectedArray > -1 && this.multiSelectKeyPressed) {
this.unselect(item);
}
this.addClass( item, this.hoverClass );
this.addClass(item, this.hoverClass);
};

@@ -553,12 +572,13 @@

* Logic when an item is de-selected
*
*
* @param {Node} item – selected item.
* @param {Boolean} force – forces through.
*/
DragSelect.prototype._handleUnselection = function( item, force ) {
DragSelect.prototype._handleUnselection = function(item, force) {
if (!this.hasClass(item, this.hoverClass) && !force) {
return false;
}
var posInSelectedArray = this.selected.indexOf(item);
var isInPrevSelection = this._prevSelected.indexOf(item); // #9
if( !this.hasClass( item, this.hoverClass ) && !force ) { return false; }
var posInSelectedArray = this.selected.indexOf( item );
var isInPrevSelection = this._prevSelected.indexOf( item ); // #9
/**

@@ -571,10 +591,9 @@ * Special algorithm for issue #9.

*/
if( posInSelectedArray > -1 && isInPrevSelection < 0 ) {
this.unselect( item );
} else if ( posInSelectedArray < 0 && isInPrevSelection > -1 ) {
this.select( item );
if (posInSelectedArray > -1 && isInPrevSelection < 0) {
this.unselect(item);
} else if (posInSelectedArray < 0 && isInPrevSelection > -1) {
this.select(item);
}
this.removeClass( item, this.hoverClass );
this.removeClass(item, this.hoverClass);
};

@@ -584,18 +603,20 @@

* Adds an item to the selection.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.select = function( item ) {
DragSelect.prototype.select = function(item) {
if (this.selected.indexOf(item) > -1) {
return false;
}
if( this.selected.indexOf(item) > -1) { return false; }
this.selected.push(item);
this.addClass(item, this.selectedClass);
this.selected.push( item );
this.addClass( item, this.selectedClass );
this.selectCallback(item);
if (this._breaked) {
return false;
}
this.selectCallback( item );
if( this._breaked ) { return false; }
return item;
};

@@ -605,18 +626,20 @@

* Removes an item from the selection.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.unselect = function( item ) {
DragSelect.prototype.unselect = function(item) {
if (this.selected.indexOf(item) < 0) {
return false;
}
if( this.selected.indexOf(item) < 0) { return false; }
this.selected.splice(this.selected.indexOf(item), 1);
this.removeClass(item, this.selectedClass);
this.selected.splice( this.selected.indexOf(item), 1 );
this.removeClass( item, this.selectedClass );
this.unselectCallback( item );
if( this._breaked ) { return false; }
this.unselectCallback(item);
if (this._breaked) {
return false;
}
return item;
};

@@ -627,41 +650,35 @@

* If it is already selected = remove, if not = add.
*
*
* @param {Node} item – item to select.
* @return {Node} item
*/
DragSelect.prototype.toggle = function( item ) {
if( this.selected.indexOf( item ) > -1) {
this.unselect( item );
} else {
this.select( item );
}
return item;
};
DragSelect.prototype.toggle = function(item) {
if (this.selected.indexOf(item) > -1) {
this.unselect(item);
} else {
this.select(item);
}
return item;
};
/**
* Checks if element is touched by the selector (and vice-versa)
*
*
* @param {Node} element – item.
* @param {Node} container – selector.
* @param {Node} area – surrounding area.
* @param {Object} selectionRect – Container bounds:
Example: {
y: this.selector.getBoundingClientRect().top + scroll.y,
x: this.selector.getBoundingClientRect().left + scroll.x,
h: this.selector.offsetHeight,
w: this.selector.offsetWidth
};
* @param {Object} scroll – Scroll x, y values.
* @return {Boolean}
*/
DragSelect.prototype.isElementTouching = function( element, container, area ) {
/**
* calculating everything here on every move consumes more performance
* but makes sure to get the right positions even if the containers are
* resized or moved on the fly. This also makes the function kinda context independant.
*/
var scroll = this.getScroll( area );
var containerRect = {
y: container.getBoundingClientRect().top + scroll.y,
x: container.getBoundingClientRect().left + scroll.x,
h: container.offsetHeight || element.getBoundingClientRect().height,
w: container.offsetWidth || element.getBoundingClientRect().width
};
DragSelect.prototype._isElementTouching = function(
element,
selectionRect,
scroll
) {
var elementRect = {

@@ -688,16 +705,13 @@ y: element.getBoundingClientRect().top + scroll.y,

if (
containerRect.x < elementRect.x + elementRect.w &&
containerRect.x + containerRect.w > elementRect.x &&
containerRect.y < elementRect.y + elementRect.h &&
containerRect.h + containerRect.y > elementRect.y
selectionRect.x < elementRect.x + elementRect.w &&
selectionRect.x + selectionRect.w > elementRect.x &&
selectionRect.y < elementRect.y + elementRect.h &&
selectionRect.h + selectionRect.y > elementRect.y
) {
return true; // collision detected!
}
else {
} else {
return false;
}
};
// Autoscroll

@@ -708,16 +722,19 @@ //////////////////////////////////////////////////////////////////////////////////////

* Automatically Scroll the area by selecting
*
*
* @param {Object} event – event object.
*/
DragSelect.prototype._autoScroll = function( event ) {
DragSelect.prototype._autoScroll = function(event) {
var edge = this.isCursorNearEdge(event, this.area);
var edge = this.isCursorNearEdge( event, this.area );
var _area = this.area === document ? document.documentElement || document.body : this.area;
var _area = this.area === document ? this.area.body : this.area;
if( edge === 'top' && _area.scrollTop > 0 ) { _area.scrollTop -= 1 * this.autoScrollSpeed; }
else if( edge === 'bottom' ) { _area.scrollTop += 1 * this.autoScrollSpeed; }
else if( edge === 'left' && _area.scrollLeft > 0 ) { _area.scrollLeft -= 1 * this.autoScrollSpeed; }
else if( edge === 'right' ) { _area.scrollLeft += 1 * this.autoScrollSpeed; }
if (edge === 'top' && _area.scrollTop > 0) {
_area.scrollTop -= 1 * this.autoScrollSpeed;
} else if (edge === 'bottom') {
_area.scrollTop += 1 * this.autoScrollSpeed;
} else if (edge === 'left' && _area.scrollLeft > 0) {
_area.scrollLeft -= 1 * this.autoScrollSpeed;
} else if (edge === 'right') {
_area.scrollLeft += 1 * this.autoScrollSpeed;
}
};

@@ -727,3 +744,3 @@

* Check if the selector is near an edge of the area
*
*
* @param {Object} event – event object.

@@ -733,7 +750,6 @@ * @param {Node} area – the area.

*/
DragSelect.prototype.isCursorNearEdge = function( event, area ) {
DragSelect.prototype.isCursorNearEdge = function(event, area) {
var cursorPosition = this._getCursorPos(event, area);
var areaRect = this.getAreaRect(area);
var cursorPosition = this._getCursorPos( event, area );
var areaRect = this.getAreaRect( area );
var tolerance = {

@@ -744,12 +760,15 @@ x: Math.max(areaRect.width / 10, 30),

if( cursorPosition.y < tolerance.y ) { return 'top'; }
else if( areaRect.height - cursorPosition.y < tolerance.y ) { return 'bottom'; }
else if( areaRect.width - cursorPosition.x < tolerance.x ) { return 'right'; }
else if( cursorPosition.x < tolerance.x ) { return 'left'; }
if (cursorPosition.y < tolerance.y) {
return 'top';
} else if (areaRect.height - cursorPosition.y < tolerance.y) {
return 'bottom';
} else if (areaRect.width - cursorPosition.x < tolerance.x) {
return 'right';
} else if (cursorPosition.x < tolerance.x) {
return 'left';
}
return false;
};
// Ending

@@ -761,12 +780,13 @@ //////////////////////////////////////////////////////////////////////////////////////

*/
DragSelect.prototype.reset = function( event ) {
DragSelect.prototype.reset = function(event) {
this.previousCursorPos = this._getCursorPos(event, this.area);
document.removeEventListener('mouseup', this.reset);
this.area.removeEventListener('mousemove', this._handleMove);
this.area.addEventListener('mousedown', this._startUp);
this.previousCursorPos = this._getCursorPos( event, this.area );
document.removeEventListener( 'mouseup', this.reset );
this.area.removeEventListener( 'mousemove', this._handleMove );
this.area.addEventListener( 'mousedown', this._startUp );
this.callback(this.selected, event);
if (this._breaked) {
return false;
}
this.callback( this.selected, event );
if( this._breaked ) { return false; }
this.selector.style.width = '0';

@@ -776,6 +796,9 @@ this.selector.style.height = '0';

setTimeout(function() { // debounce in order "onClick" to work
this.mouseInteraction = false;
}.bind(this), 100);
setTimeout(
function() {
// debounce in order "onClick" to work
this.mouseInteraction = false;
}.bind(this),
100
);
};

@@ -789,8 +812,10 @@

DragSelect.prototype.break = function() {
this._breaked = true;
setTimeout(function() { // debounce the break should only break once instantly after call
this._breaked = false;
}.bind(this), 100);
setTimeout(
function() {
// debounce the break should only break once instantly after call
this._breaked = false;
}.bind(this),
100
);
};

@@ -802,10 +827,7 @@

DragSelect.prototype.stop = function() {
this.reset();
this.area.removeEventListener( 'mousedown', this._startUp );
document.removeEventListener( 'mouseup', this.reset );
this.area.removeEventListener('mousedown', this._startUp);
document.removeEventListener('mouseup', this.reset);
};
// Usefull methods for user

@@ -816,9 +838,7 @@ //////////////////////////////////////////////////////////////////////////////////////

* Returns the current selected nodes
*
*
* @return {Nodes}
*/
DragSelect.prototype.getSelection = function() {
return this.selected;
};

@@ -829,3 +849,3 @@

* Will be relative to an area including the scroll unless advised otherwise
*
*
* @param {Object} event

@@ -836,10 +856,11 @@ * @param {Node} _area – containing area / this.area if none / document if === false

*/
DragSelect.prototype.getCursorPos = function( event, _area, ignoreScroll ) {
DragSelect.prototype.getCursorPos = function(event, _area, ignoreScroll) {
if (!event) {
return false;
}
if(!event) { return false; }
var area = _area || (_area !== false && this.area);
var pos = this._getCursorPos(event, area);
var scroll = ignoreScroll ? { x: 0, y: 0 } : this.getScroll(area);
var area = _area || _area !== false && this.area;
var pos = this._getCursorPos( event, area );
var scroll = ignoreScroll ? { x: 0, y: 0 } : this.getScroll( area );
return {

@@ -857,3 +878,3 @@ x: pos.x + scroll.x,

* Can add multiple nodes at once, in contrary to .select
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -864,16 +885,22 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.addSelection = function( _nodes, _callback, dontAddToSelectables ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.addSelection = function(
_nodes,
_callback,
dontAddToSelectables
) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
this.select( node );
this.select(node);
}
if( !dontAddToSelectables ) { this.addSelectables( nodes ); }
if( _callback ) { this.callback( this.selected, false ); }
if (!dontAddToSelectables) {
this.addSelectables(nodes);
}
if (_callback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -884,3 +911,3 @@

* Multiple nodes can be given at once, in contrary to unselect
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -891,16 +918,22 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.removeSelection = function( _nodes, _callback, removeFromSelectables ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.removeSelection = function(
_nodes,
_callback,
removeFromSelectables
) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
this.unselect( node );
this.unselect(node);
}
if( removeFromSelectables ) { this.removeSelectables( nodes ); }
if( _callback ) { this.callback( this.selected, false ); }
if (removeFromSelectables) {
this.removeSelectables(nodes);
}
if (_callback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -912,3 +945,3 @@

* Multiple nodes can be given at once.
*
*
* @param {Nodes} _nodes one or multiple nodes

@@ -919,23 +952,16 @@ * @param {Boolean} _callback - if callback should be called

*/
DragSelect.prototype.toggleSelection = function( _nodes, _callback, _special ) {
var nodes = this.toArray( _nodes );
DragSelect.prototype.toggleSelection = function(_nodes, _callback, _special) {
var nodes = this.toArray(_nodes);
for (var index = 0, il = nodes.length; index < il; index++) {
var node = nodes[index];
if( this.selected.indexOf( node ) < 0 ) {
this.addSelection( node, _callback, _special );
if (this.selected.indexOf(node) < 0) {
this.addSelection(node, _callback, _special);
} else {
this.removeSelection( node, _callback, _special );
this.removeSelection(node, _callback, _special);
}
}
return this.selected;
};

@@ -945,3 +971,3 @@

* Sets the current selected nodes and optionally run the callback
*
*
* @param {Nodes} _nodes – dom nodes

@@ -952,9 +978,11 @@ * @param {Boolean} runCallback - if callback should be called

*/
DragSelect.prototype.setSelection = function( _nodes, runCallback, dontAddToSelectables ) {
DragSelect.prototype.setSelection = function(
_nodes,
runCallback,
dontAddToSelectables
) {
this.clearSelection();
this.addSelection( _nodes, runCallback, dontAddToSelectables );
this.addSelection(_nodes, runCallback, dontAddToSelectables);
return this.selected;
};

@@ -964,18 +992,18 @@

* Unselect / Deselect all current selected Nodes
*
*
* @param {Boolean} runCallback - if callback should be called
* @return {Array} this.selected, should be empty
*/
DragSelect.prototype.clearSelection = function( runCallback ) {
DragSelect.prototype.clearSelection = function(runCallback) {
var selection = this.selected.slice();
for (var index = 0, il = selection.length; index < il; index++) {
var node = selection[index];
this.unselect( node );
this.unselect(node);
}
if( runCallback ) { this.callback( this.selected, false ); }
if (runCallback) {
this.callback(this.selected, false);
}
return this.selected;
};

@@ -986,3 +1014,3 @@

* The algorithm makes sure that no node is added twice
*
*
* @param {Nodes} _nodes – dom nodes

@@ -992,8 +1020,6 @@ * @param {Boolean} addToSelection – if elements should also be added to current selection

*/
DragSelect.prototype.addSelectables = function( _nodes, addToSelection ) {
var nodes = this.toArray( _nodes );
this._handleSelectables( nodes, false, addToSelection );
DragSelect.prototype.addSelectables = function(_nodes, addToSelection) {
var nodes = this.toArray(_nodes);
this._handleSelectables(nodes, false, addToSelection);
return _nodes;
};

@@ -1003,9 +1029,7 @@

* Gets all nodes that can be selected
*
*
* @return {Nodes} this.selectables
*/
DragSelect.prototype.getSelectables = function() {
return this.selectables;
};

@@ -1018,3 +1042,3 @@

* thus replacing the original set.
*
*
* @param {Nodes} _nodes – dom nodes

@@ -1025,7 +1049,9 @@ * @param {Boolean} removeFromSelection – if elements should also be removed from current selection

*/
DragSelect.prototype.setSelectables = function( _nodes, removeFromSelection, addToSelection ) {
this.removeSelectables( this.getSelectables(), removeFromSelection );
return this.addSelectables( _nodes, addToSelection );
DragSelect.prototype.setSelectables = function(
_nodes,
removeFromSelection,
addToSelection
) {
this.removeSelectables(this.getSelectables(), removeFromSelection);
return this.addSelectables(_nodes, addToSelection);
};

@@ -1035,3 +1061,3 @@

* Remove nodes from the nodes that can be selected.
*
*
* @param {Nodes} _nodes – dom nodes

@@ -1041,11 +1067,8 @@ * @param {Boolean} removeFromSelection – if elements should also be removed from current selection

*/
DragSelect.prototype.removeSelectables = function( _nodes, removeFromSelection ) {
var nodes = this.toArray( _nodes );
this._handleSelectables( nodes, true, removeFromSelection );
DragSelect.prototype.removeSelectables = function(_nodes, removeFromSelection) {
var nodes = this.toArray(_nodes);
this._handleSelectables(nodes, true, removeFromSelection);
return _nodes;
};
// Helpers

@@ -1058,23 +1081,24 @@ //////////////////////////////////////////////////////////////////////////////////////

* (found @ https://stackoverflow.com/a/2405835)
*
* @param {Object} event
*
* @param {Object} event
* @return {Boolean}
*/
DragSelect.prototype.isRightClick = function( event ) {
DragSelect.prototype.isRightClick = function(event) {
if (!event) {
return false;
}
if( !event ) { return false; }
var isRightMB = false;
if ('which' in event) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
isRightMB = event.which === 3;
} else if ('button' in event) { // IE, Opera
isRightMB = event.button === 2;
if ('which' in event) {
// Gecko (Firefox), WebKit (Safari/Chrome) & Opera
isRightMB = event.which === 3;
} else if ('button' in event) {
// IE, Opera
isRightMB = event.button === 2;
}
return isRightMB;
};
/**

@@ -1084,17 +1108,21 @@ * Adds a class to an element

* all credits to http://clubmate.fi/javascript-adding-and-removing-class-names-from-elements/
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Node} element
*/
DragSelect.prototype.addClass = function( element, classname ) {
DragSelect.prototype.addClass = function(element, classname) {
if (element.classList) {
return element.classList.add(classname);
}
if(element.classList) { return element.classList.add(classname); }
var cn = element.getAttribute('class') || '';
if( cn.indexOf(classname) !== -1 ) { return element; } // test for existance
if( cn !== '' ) { classname = ' ' + classname; } // add a space if the element already has class
element.setAttribute('class', cn+classname);
if (cn.indexOf(classname) !== -1) {
return element;
} // test for existance
if (cn !== '') {
classname = ' ' + classname;
} // add a space if the element already has class
element.setAttribute('class', cn + classname);
return element;
};

@@ -1106,17 +1134,17 @@

* all credits to http://clubmate.fi/javascript-adding-and-removing-class-names-from-elements/
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Node} element
*/
DragSelect.prototype.removeClass = function( element, classname ) {
DragSelect.prototype.removeClass = function(element, classname) {
if (element.classList) {
return element.classList.remove(classname);
}
if(element.classList) { return element.classList.remove(classname); }
var cn = element.getAttribute('class') || '';
var rxp = new RegExp( classname + '\\b', 'g' );
cn = cn.replace( rxp, '' );
var rxp = new RegExp(classname + '\\b', 'g');
cn = cn.replace(rxp, '');
element.setAttribute('class', cn);
return element;
};

@@ -1127,15 +1155,18 @@

* sadly legacy phones/browsers don’t support .classlist so we use this workaround
*
* @param {Node} element
* @param {String} classname
*
* @param {Node} element
* @param {String} classname
* @return {Boolean}
*/
DragSelect.prototype.hasClass = function( element, classname ) {
DragSelect.prototype.hasClass = function(element, classname) {
if (element.classList) {
return element.classList.contains(classname);
}
if(element.classList) { return element.classList.contains(classname); }
var cn = element.getAttribute('class') || '';
if( cn.indexOf( classname ) > -1 ) { return true; }
else { return false; }
if (cn.indexOf(classname) > -1) {
return true;
} else {
return false;
}
};

@@ -1146,13 +1177,16 @@

* so user doesn’t have to care.
*
*
* @param {Node} nodes
* @return {array}
*/
DragSelect.prototype.toArray = function( nodes ) {
DragSelect.prototype.toArray = function(nodes) {
if (!nodes) {
return false;
}
if (!nodes.length && this.isElement(nodes)) {
return [nodes];
}
if( !nodes ) { return false; }
if( !nodes.length && this.isElement( nodes ) ) { return [nodes]; }
var array = [];
for ( var i = nodes.length - 1; i >= 0; i-- ) {
for (var i = nodes.length - 1; i >= 0; i--) {
array[i] = nodes[i];

@@ -1162,3 +1196,2 @@ }

return array;
};

@@ -1168,22 +1201,22 @@

* Checks if a node is of type element
* all credits to vikynandha: https://gist.github.com/vikynandha/6539809
*
* all credits to vikynandha: https://gist.github.com/vikynandha/6539809
*
* @param {Node} node
* @return {Boolean}
*/
DragSelect.prototype.isElement = function( node ) {
try { // Using W3 DOM2 (works for FF, Opera and Chrome), also checking for SVGs
DragSelect.prototype.isElement = function(node) {
try {
// Using W3 DOM2 (works for FF, Opera and Chrome), also checking for SVGs
return node instanceof HTMLElement || node instanceof SVGElement;
}
catch( e ){
} catch (e) {
// Browsers not supporting W3 DOM2 don't have HTMLElement and
// an exception is thrown and we end up here. Testing some
// properties that all elements have. (works even on IE7)
return ( typeof node === 'object' ) &&
( node.nodeType === 1 ) &&
( typeof node.style === 'object' ) &&
( typeof node.ownerDocument === 'object' );
return (
typeof node === 'object' &&
node.nodeType === 1 &&
typeof node.style === 'object' &&
typeof node.ownerDocument === 'object'
);
}
};

@@ -1196,3 +1229,3 @@

* Use the public .getCursorPos() from outside, it’s more flexible
*
*
* @param {Object} event

@@ -1202,6 +1235,9 @@ * @param {Node} area – containing area / document if none

*/
DragSelect.prototype._getCursorPos = function( event, area ) {
if(!event) { return { x: 0, y: 0 }; }
DragSelect.prototype._getCursorPos = function(event, area) {
if (!event) {
return { x: 0, y: 0 };
}
var cPos = { // event.clientX/Y fallback for <IE8
var cPos = {
// event.clientX/Y fallback for <IE8
x: event.pageX || event.clientX,

@@ -1211,10 +1247,10 @@ y: event.pageY || event.clientY

var areaRect = this.getAreaRect( area || document );
var docScroll = this.getScroll(); // needed when document is scrollable but area is not
var areaRect = this.getAreaRect(area || document);
var docScroll = this.getScroll(); // needed when document is scrollable but area is not
return { // if it’s constrained in an area the area should be substracted calculate
return {
// if it’s constrained in an area the area should be substracted calculate
x: cPos.x - areaRect.left - docScroll.x,
y: cPos.y - areaRect.top - docScroll.y
};
};

@@ -1224,7 +1260,7 @@

* Returns the starting/initial position of the cursor/selector
*
*
* @return {Object} initialPos.
*/
DragSelect.prototype.getInitialCursorPosition = function() {
return this.initialCursorPos;
return this.initialCursorPos;
};

@@ -1234,3 +1270,3 @@

* Returns the last seen position of the cursor/selector
*
*
* @return {Object} initialPos.

@@ -1248,3 +1284,3 @@ */

DragSelect.prototype.getPreviousCursorPosition = function() {
return this.previousCursorPos;
return this.previousCursorPos;
};

@@ -1260,6 +1296,9 @@

*/
DragSelect.prototype.getCursorPositionDifference = function( usePreviousCursorDifference ) {
DragSelect.prototype.getCursorPositionDifference = function(
usePreviousCursorDifference
) {
var posA = this.getCurrentCursorPosition();
var posB = usePreviousCursorDifference ? this.getPreviousCursorPosition() : this.getInitialCursorPosition();
var posB = usePreviousCursorDifference
? this.getPreviousCursorPosition()
: this.getInitialCursorPosition();

@@ -1270,3 +1309,2 @@ return {

};
};

@@ -1277,14 +1315,20 @@

* If container has no scroll it will return 0
*
*
* @param {Node} area
* @return {Object} scroll X/Y
*/
DragSelect.prototype.getScroll = function( area ) {
DragSelect.prototype.getScroll = function(area) {
var body = {
top: document.body.scrollTop > 0 ? document.body.scrollTop : document.documentElement.scrollTop,
left: document.body.scrollLeft > 0 ? document.body.scrollLeft : document.documentElement.scrollLeft
top:
document.body.scrollTop > 0
? document.body.scrollTop
: document.documentElement.scrollTop,
left:
document.body.scrollLeft > 0
? document.body.scrollLeft
: document.documentElement.scrollLeft
};
var scroll = { // when the rectangle is bound to the document, no scroll is needed
var scroll = {
// when the rectangle is bound to the document, no scroll is needed
y: area && area.scrollTop >= 0 ? area.scrollTop : body.top,

@@ -1295,3 +1339,2 @@ x: area && area.scrollLeft >= 0 ? area.scrollLeft : body.left

return scroll;
};

@@ -1303,14 +1346,26 @@

* except the sizes will be nulled.
*
* @param {Node} area
*
* @param {Node} area
* @return {Object}
*/
DragSelect.prototype.getAreaRect = function( area ) {
if(area === document) {
DragSelect.prototype.getAreaRect = function(area) {
if (area === document) {
var size = {
y: area.documentElement.clientHeight > 0 ? area.documentElement.clientHeight : window.innerHeight,
x: area.documentElement.clientWidth > 0 ? area.documentElement.clientWidth : window.innerWidth
y:
area.documentElement.clientHeight > 0
? area.documentElement.clientHeight
: window.innerHeight,
x:
area.documentElement.clientWidth > 0
? area.documentElement.clientWidth
: window.innerWidth
};
return { top: 0, left: 0, bottom: 0, right: 0, width: size.x, height: size.y };
return {
top: 0,
left: 0,
bottom: 0,
right: 0,
width: size.x,
height: size.y
};
}

@@ -1326,3 +1381,2 @@

};
};

@@ -1333,10 +1387,9 @@

* height values accordingly.
*
*
* @param {Node} node
* @param {Object} pos { x, y, w, h }
*
*
* @return {Node}
*/
DragSelect.prototype.updatePos = function( node, pos ) {
DragSelect.prototype.updatePos = function(node, pos) {
node.style.left = pos.x + 'px';

@@ -1347,24 +1400,23 @@ node.style.top = pos.y + 'px';

return node;
};
// Make exportable
//////////////////////////////////////////////////////////////////////////////////////
// jshint -W117
/* eslint-disable no-undef */
// Module exporting
if ( typeof module !== 'undefined' && module !== null ) {
if (typeof module !== 'undefined' && module !== null) {
module.exports = DragSelect;
// AMD Modules
} else if( typeof define !== 'undefined' && typeof define === 'function' && define ) {
define(function() { return DragSelect; });
// AMD Modules
} else if (
typeof define !== 'undefined' &&
typeof define === 'function' &&
define
) {
define(function() {
return DragSelect;
});
} else {
window.DragSelect = DragSelect;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc