support drag and drop for playlist items
25
dashboard-ui/bower_components/dragula.js/.bower.json
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "dragula.js",
|
||||
"version": "3.5.1",
|
||||
"description": "Drag and drop so simple it hurts",
|
||||
"main": [
|
||||
"dist/dragula.js",
|
||||
"dist/dragula.css"
|
||||
],
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/bevacqua/dragula",
|
||||
"authors": [
|
||||
"Nicolas Bevacqua <nicolasbevacqua@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"_release": "3.5.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v3.5.1",
|
||||
"commit": "bbd33f7f871d2f672bebf70bfc054134a48cf0e9"
|
||||
},
|
||||
"_source": "git://github.com/bevacqua/dragula.git",
|
||||
"_target": "~3.5.1",
|
||||
"_originalSource": "dragula",
|
||||
"_direct": true
|
||||
}
|
13
dashboard-ui/bower_components/dragula.js/.editorconfig
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
4
dashboard-ui/bower_components/dragula.js/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
npm-debug.log
|
||||
.DS_Store
|
||||
Thumbs.db
|
4
dashboard-ui/bower_components/dragula.js/.jshintignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
bower_components
|
||||
dist
|
||||
example
|
23
dashboard-ui/bower_components/dragula.js/.jshintrc
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"noempty": true,
|
||||
"nonew": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"trailing": true,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"strict": true,
|
||||
"immed": true,
|
||||
"expr": true,
|
||||
"latedef": "nofunc",
|
||||
"quotmark": "single",
|
||||
"validthis": true,
|
||||
"indent": 2,
|
||||
"node": true,
|
||||
"browser": true
|
||||
}
|
6
dashboard-ui/bower_components/dragula.js/.travis.yml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 'iojs'
|
||||
- '4'
|
||||
before_script:
|
||||
- export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
|
15
dashboard-ui/bower_components/dragula.js/bower.json
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "dragula.js",
|
||||
"version": "3.5.1",
|
||||
"description": "Drag and drop so simple it hurts",
|
||||
"main": [
|
||||
"dist/dragula.js",
|
||||
"dist/dragula.css"
|
||||
],
|
||||
"ignore": [],
|
||||
"homepage": "https://github.com/bevacqua/dragula",
|
||||
"authors": [
|
||||
"Nicolas Bevacqua <nicolasbevacqua@gmail.com>"
|
||||
],
|
||||
"license": "MIT"
|
||||
}
|
228
dashboard-ui/bower_components/dragula.js/changelog.markdown
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
# 3.5.1 Which Hunt
|
||||
|
||||
- Fixed a bug when determining the mouse button being pressed
|
||||
- Fixed a bug when determining the element behind the mouse cursor when `ignoreInputTextSelection` was enabled
|
||||
|
||||
# 3.5.0 Input Fanatic
|
||||
|
||||
- Added a feature where users are able to select text ranges with their mouse in inputs within a dragula container
|
||||
|
||||
# 3.4.1 Input Accomodation
|
||||
|
||||
- Fixed a bug where text in inputs inside containers assigned to `dragula` couldn't be selected
|
||||
|
||||
# 3.4.0 Event Sourcing
|
||||
|
||||
- Events for `cancel`, `remove`, and `shadow` now all provide a `source` parameter in the third position
|
||||
|
||||
# 3.3.2 Captain Obvious
|
||||
|
||||
- Fixed a bug where `out` would be emitted with an `undefined` container
|
||||
|
||||
# 3.3.1 Significant Other
|
||||
|
||||
- Fixed a fringe bug [(#207)](https://github.com/bevacqua/dragula/pull/207) where the click handler wouldn't work
|
||||
- Fixed a bug where `drop` events would sometimes not receive the current sibling
|
||||
|
||||
# 3.3.0 Brotherhood
|
||||
|
||||
- The `options.moves` callback now receives a fourth parameter, the `sibling` found after `el`
|
||||
- The `drop` event now receives a fourth parameter, the `sibling` found after `el`
|
||||
|
||||
# 3.2.0 Sortable Sauce
|
||||
|
||||
- You can now use `options.copySortSource` to enable sorting in `copy`-source containers
|
||||
|
||||
# 3.1.0 Copy Paste
|
||||
|
||||
- You can now set `options.copy` to a method. It'll be invoked once per drag to ask whether the element being dragged should be treated as a copy or not
|
||||
- Fixed a bug where starting a drag programatically while an element was being dragged resulted in an exception
|
||||
|
||||
# 3.0.7 Crossroads
|
||||
|
||||
- Fixed a bug in Webpack builds by updating `crossvent` to `1.5.3`
|
||||
|
||||
# 3.0.5 Mouse Rat Rock Band
|
||||
|
||||
- Fixed a bug where `mousedown` would be prevented and focusing draggable inputs wouldn't be possible
|
||||
|
||||
# 3.0.4 IE is the old IE
|
||||
|
||||
- Fixed a bug in IE8 by updating `crossvent` to `1.5.2`
|
||||
|
||||
# 3.0.3 Forest Fire
|
||||
|
||||
- Fixed a bug in Firefox where dragging links and images would result in issues
|
||||
|
||||
# 3.0.2 Clickhood Rainforest
|
||||
|
||||
- Fixed a _historical_ bug, where click on anchors would be ignored within `dragula` containers in mobile
|
||||
- Fixed a bug where events wouldn't be gracefully removed if `drake` were destroyed during a drag event
|
||||
- Now emits `dragend` after `out` to preserve consistency _(because `drag` is emitted before `over`)_
|
||||
- Fixed another old bug where attempting to remove elements using `removeOnSpill` on mobile would fail
|
||||
|
||||
# 3.0.1 Carjacking
|
||||
|
||||
- Fixed a bug in mobile, caused by `3.0.0`, where scrolling would be impossible
|
||||
- Fixed a bug where dragging would cause text selection in IE8
|
||||
|
||||
# 3.0.0 Guilty Conscience
|
||||
|
||||
- Removed `addContainer` method, which was previously deprecated
|
||||
- Removed `removeContainer` method, which was previously deprecated
|
||||
- Removed `delay` option in favor of using `mousemove`
|
||||
- Drag events now start on the first occurrence of a `mousemove` event
|
||||
- If `mousemove` never fires, then the `drag` machinery won't start, either
|
||||
- Changed default value for `invalid`, now always returns `false` by default
|
||||
- Added `mirrorContainer` option to determine where the mirror gets appended to _(defaults to `document.body`)_
|
||||
|
||||
# 2.1.2 Shady Sibling
|
||||
|
||||
- Fixed a bug where `shadow` would trigger multiple times while dragging an element over the same spot
|
||||
|
||||
# 2.1.1 Classy Drake
|
||||
|
||||
- Fixed a bug where adding and removing classes might've caused issues on elements that had foreign CSS classes
|
||||
- Added an argument to `cloned` event that specifies the kind of clone. Possible values include `mirror` and `copy` at the moment
|
||||
|
||||
# 2.1.0 Over and Out
|
||||
|
||||
- Added `over` event that fires whenever an element is dragged over a container _(or whenever a drag event starts)_
|
||||
- Added `out` event that fires whenever an element is dragged out of a container _(or whenever a drag event ends)_
|
||||
|
||||
# 2.0.7 Mayhem
|
||||
|
||||
- Fixed a bug caused in `2.0.6` where anything would be regarded as a `drake` container
|
||||
|
||||
# 2.0.6 Coruscant
|
||||
|
||||
- Fixed a bug where `isContainer` would be called with a `el=null` in some situations
|
||||
|
||||
# 2.0.5 Cross Ventilation
|
||||
|
||||
- Bumped `crossvent@1.5.0`
|
||||
|
||||
# 2.0.4 Transit Overload
|
||||
|
||||
- Set `gu-transit` after a drag event has fully started
|
||||
|
||||
# 2.0.3 Mice Trap
|
||||
|
||||
- Fixed a bug where using `.cancel` would throw an exception
|
||||
|
||||
# 2.0.2 Aural Emission
|
||||
|
||||
- Replaced `contra.emitter` with `contra@1.9.1/emitter`
|
||||
|
||||
# 2.0.1 Copycat
|
||||
|
||||
- Fixed a bug where dragging a copy back to origin after hovering over another container would still result in a copy being made if you never spilled the item
|
||||
|
||||
# 2.0.0 Containerization
|
||||
|
||||
- Deprecated `addContainer` method
|
||||
- Deprecated `removeContainer` method
|
||||
- Exposed `dragula.containers` collection
|
||||
- Introduced dynamic `isContainer` method
|
||||
- Can now omit `containers` argument to `dragula(containers, options)`
|
||||
- Can now pass `containers` as an option
|
||||
|
||||
# 1.7.0 Clickety Click
|
||||
|
||||
- Differentiate between drag and click using `delay` option
|
||||
- Ability to specify which event targets are `invalid` drag triggers
|
||||
|
||||
# 1.6.1 Shadow Drake
|
||||
|
||||
- Improved shadow positioning when `revertOnSpill` is `true`
|
||||
|
||||
# 1.6.0 Lonely Clown Clone
|
||||
|
||||
- Added `'cloned'` event when a DOM element is cloned
|
||||
|
||||
# 1.5.1 Touchypants
|
||||
|
||||
- Fixed an issue where dragula didn't understand where an element was being dropped
|
||||
|
||||
# 1.5.0 Drag Racing
|
||||
|
||||
- Introduced drag handles so that elements could only be dragged from a handle element
|
||||
|
||||
# 1.4.2 Container Camp
|
||||
|
||||
- Fixed a bug where `addContainer` and `removeContainer` wouldn't update the list of available containers
|
||||
- Fixed a bug where `document.body` would be accessed before it was available if the scripts were loaded in the `<head>`
|
||||
|
||||
# 1.4.1 Blood Prince
|
||||
|
||||
- Fixed an issue where manually started drag events wouldn't know if position changed when an item was dropped in the source container
|
||||
- Added minor styling to `gu-mirror`, to visually identify that a drag is in progress
|
||||
|
||||
# 1.4.0 Top Fuel
|
||||
|
||||
- Added a `dragend` event that's always fired
|
||||
- Added a `dragging` property to API
|
||||
- Introduced manual `start` API method
|
||||
- Introduced `addContainer` and `removeContainer` dynamic API
|
||||
|
||||
# 1.3.0 Terror
|
||||
|
||||
Introduced an `.end` instance API method that gracefully ends the drag event using the last known valid drop target.
|
||||
|
||||
# 1.2.4 Brother in Arms
|
||||
|
||||
- The `accepts` option now takes a fourth argument, `sibling`, giving us a hint of the precise position the item would be dropped in
|
||||
|
||||
# 1.2.3 Breeding Pool
|
||||
|
||||
- Fixed a bug in cross browser behavior that caused the hover effect to ignore scrolling
|
||||
- Fixed a bug where touch events weren't working in obscure versions of IE
|
||||
|
||||
# 1.2.2 Originality Accepted
|
||||
|
||||
- Improved `accepts` mechanism so that it always accepts the original starting point
|
||||
|
||||
# 1.2.1 Firehose
|
||||
|
||||
- Fixed a bug introduced in `1.2.0`
|
||||
- Fixed a bug where cancelling with `revert` enabled wouldn't respect sort order
|
||||
|
||||
# 1.2.0 Firefly
|
||||
|
||||
- Introduced `moves` option, used to determine if an item is draggable
|
||||
- Added a `source` parameter for the `drop` event
|
||||
- Cancelling a drag event when `revertOnSpill` is `true` will now move the element to its original position in the source element instead of appending it
|
||||
- Fixed a bug where _"cancellations"_ that ended up leaving the dragged element in the source container but changed sort order would trigger a `cancel` event instead of `drop`
|
||||
- Fixed a bug where _"drops"_ that ended up leaving the element in the exact same place it was dragged from would end up triggering a `drop` event instead of `cancel`
|
||||
- Added touch event support
|
||||
|
||||
# 1.1.4 Fog Creek
|
||||
|
||||
- Added `'shadow'` event to enable easy updates to shadow element as it's moved
|
||||
|
||||
# 1.1.3 Drag Queen
|
||||
|
||||
- Fixed a bug where `dragula` wouldn't make a copy if the element was dropped outside of a target container
|
||||
- If a dragged element gets removed for an instance that has `copy` set to `true`, a `cancel` event is raised instead
|
||||
|
||||
# 1.1.2 Eavesdropping
|
||||
|
||||
- Fixed a bug where _"cancellations"_ that ended up leaving the dragged element somewhere other than the source container wouldn't trigger a `drop` event
|
||||
|
||||
# 1.1.1 Slipping Jimmy
|
||||
|
||||
- Fixed a bug where the movable shadow wouldn't update properly if the element was hovered over the last position of a container
|
||||
|
||||
# 1.1.0 Age of Shadows
|
||||
|
||||
- Added a movable shadow that gives visual feedback as to where a dragged item would be dropped
|
||||
- Added an option to remove dragged elements when they are dropped outside of sanctioned containers
|
||||
- Added an option to revert dragged elements back to their source container when they are dropped outside of sanctioned containers
|
||||
|
||||
# 1.0.1 Consuelo
|
||||
|
||||
- Removed `console.log` statement
|
||||
|
||||
# 1.0.0 IPO
|
||||
|
||||
- Initial Public Release
|
33
dashboard-ui/bower_components/dragula.js/classes.js
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
var cache = {};
|
||||
var start = '(?:^|\\s)';
|
||||
var end = '(?:\\s|$)';
|
||||
|
||||
function lookupClass (className) {
|
||||
var cached = cache[className];
|
||||
if (cached) {
|
||||
cached.lastIndex = 0;
|
||||
} else {
|
||||
cache[className] = cached = new RegExp(start + className + end, 'g');
|
||||
}
|
||||
return cached;
|
||||
}
|
||||
|
||||
function addClass (el, className) {
|
||||
var current = el.className;
|
||||
if (!current.length) {
|
||||
el.className = className;
|
||||
} else if (!lookupClass(className).test(current)) {
|
||||
el.className += ' ' + className;
|
||||
}
|
||||
}
|
||||
|
||||
function rmClass (el, className) {
|
||||
el.className = el.className.replace(lookupClass(className), ' ').trim();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
add: addClass,
|
||||
rm: rmClass
|
||||
};
|
60
dashboard-ui/bower_components/dragula.js/contributing.markdown
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
# Contributing
|
||||
|
||||
Hey there! Glad you want to chime in. Here's what you need to know.
|
||||
|
||||
### Support Requests
|
||||
|
||||
There's now a dedicated support channel in Slack. Visit the `dragula` [demo page][2] to get an invite. Support requests won't be handled through the repository anymore.
|
||||
|
||||
If you have a question, make sure it wasn't [already answered][1]. If it wasn't, please refer to the Slack chat. To get an invite, use the badge in the [demo page][2].
|
||||
|
||||
> Our goal is to provide answers to the most frequently asked questions somewhere in the documentation.
|
||||
|
||||
### Bugs
|
||||
|
||||
Bug reports are tricky. Please provide as much context as possible, and if you want to start working on a fix, we'll be forever grateful! Please try and test around for a bit to make sure you're dealing with a bug and not an issue in your implementation.
|
||||
|
||||
If possible, provide a demo where the bug is isolated and turned into its smallest possible representation. That would help a lot!
|
||||
|
||||
Thanks for reporting bugs, we'd be lost without you.
|
||||
|
||||
### Feature Requests
|
||||
|
||||
We're still considering feature requests. Note that we might not implement the feature you want, or exactly how you want it. The goal here is to keep making `dragula` awesome while not making it too bloated.
|
||||
|
||||
We also dislike overly specific features and favor more abstract ones you the consumer can build other features upon.
|
||||
|
||||
# Development
|
||||
|
||||
Development flows are based on `npm run` scripts.
|
||||
|
||||
### Build
|
||||
|
||||
To compile a standalone browserify module, use the following command. A minified version will also be produced. The compiled bundles are placed inside `dist`. Since **these are autogenerated**, please don't include them in your pull requests.
|
||||
|
||||
```shell
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can also run the build continuously, _to faciliate development_, with this command.
|
||||
|
||||
```shell
|
||||
npm start
|
||||
```
|
||||
|
||||
### Test
|
||||
|
||||
Run the command below to execute all tests in a DevTools window through Electron. Note that the DevTools will get reloaded whenever your test files change, making tests a breeze!
|
||||
|
||||
```shell
|
||||
npm run test-watch
|
||||
```
|
||||
|
||||
To run tests a single time, simply run the following command. This is used in CI testing.
|
||||
|
||||
```shell
|
||||
npm test
|
||||
```
|
||||
|
||||
[1]: https://github.com/bevacqua/dragula/issues?q=label%3Asupport
|
||||
[2]: http://bevacqua.github.io/dragula/
|
22
dashboard-ui/bower_components/dragula.js/dist/dragula.css
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
.gu-mirror {
|
||||
position: fixed !important;
|
||||
margin: 0 !important;
|
||||
z-index: 9999 !important;
|
||||
opacity: 0.8;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
||||
filter: alpha(opacity=80);
|
||||
}
|
||||
.gu-hide {
|
||||
display: none !important;
|
||||
}
|
||||
.gu-unselectable {
|
||||
-webkit-user-select: none !important;
|
||||
-moz-user-select: none !important;
|
||||
-ms-user-select: none !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
.gu-transit {
|
||||
opacity: 0.2;
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
||||
filter: alpha(opacity=20);
|
||||
}
|
885
dashboard-ui/bower_components/dragula.js/dist/dragula.js
vendored
Normal file
1
dashboard-ui/bower_components/dragula.js/dist/dragula.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.gu-mirror{position:fixed!important;margin:0!important;z-index:9999!important;opacity:.8;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";filter:alpha(opacity=80)}.gu-hide{display:none!important}.gu-unselectable{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.gu-transit{opacity:.2;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";filter:alpha(opacity=20)}
|
1
dashboard-ui/bower_components/dragula.js/dist/dragula.min.js
vendored
Normal file
585
dashboard-ui/bower_components/dragula.js/dragula.js
vendored
Normal file
|
@ -0,0 +1,585 @@
|
|||
'use strict';
|
||||
|
||||
var emitter = require('contra/emitter');
|
||||
var crossvent = require('crossvent');
|
||||
var classes = require('./classes');
|
||||
|
||||
function dragula (initialContainers, options) {
|
||||
var len = arguments.length;
|
||||
if (len === 1 && Array.isArray(initialContainers) === false) {
|
||||
options = initialContainers;
|
||||
initialContainers = [];
|
||||
}
|
||||
var body = document.body;
|
||||
var documentElement = document.documentElement;
|
||||
var _mirror; // mirror image
|
||||
var _source; // source container
|
||||
var _item; // item being dragged
|
||||
var _offsetX; // reference x
|
||||
var _offsetY; // reference y
|
||||
var _moveX; // reference move x
|
||||
var _moveY; // reference move y
|
||||
var _initialSibling; // reference sibling when grabbed
|
||||
var _currentSibling; // reference sibling now
|
||||
var _copy; // item used for copying
|
||||
var _renderTimer; // timer for setTimeout renderMirrorImage
|
||||
var _lastDropTarget = null; // last container item was over
|
||||
var _grabbed; // holds mousedown context until first mousemove
|
||||
|
||||
var o = options || {};
|
||||
if (o.moves === void 0) { o.moves = always; }
|
||||
if (o.accepts === void 0) { o.accepts = always; }
|
||||
if (o.invalid === void 0) { o.invalid = invalidTarget; }
|
||||
if (o.containers === void 0) { o.containers = initialContainers || []; }
|
||||
if (o.isContainer === void 0) { o.isContainer = never; }
|
||||
if (o.copy === void 0) { o.copy = false; }
|
||||
if (o.copySortSource === void 0) { o.copySortSource = false; }
|
||||
if (o.revertOnSpill === void 0) { o.revertOnSpill = false; }
|
||||
if (o.removeOnSpill === void 0) { o.removeOnSpill = false; }
|
||||
if (o.direction === void 0) { o.direction = 'vertical'; }
|
||||
if (o.ignoreInputTextSelection === void 0) { o.ignoreInputTextSelection = true; }
|
||||
if (o.mirrorContainer === void 0) { o.mirrorContainer = body; }
|
||||
|
||||
var drake = emitter({
|
||||
containers: o.containers,
|
||||
start: manualStart,
|
||||
end: end,
|
||||
cancel: cancel,
|
||||
remove: remove,
|
||||
destroy: destroy,
|
||||
dragging: false
|
||||
});
|
||||
|
||||
if (o.removeOnSpill === true) {
|
||||
drake.on('over', spillOver).on('out', spillOut);
|
||||
}
|
||||
|
||||
events();
|
||||
|
||||
return drake;
|
||||
|
||||
function isContainer (el) {
|
||||
return drake.containers.indexOf(el) !== -1 || o.isContainer(el);
|
||||
}
|
||||
|
||||
function events (remove) {
|
||||
var op = remove ? 'remove' : 'add';
|
||||
touchy(documentElement, op, 'mousedown', grab);
|
||||
touchy(documentElement, op, 'mouseup', release);
|
||||
}
|
||||
|
||||
function eventualMovements (remove) {
|
||||
var op = remove ? 'remove' : 'add';
|
||||
touchy(documentElement, op, 'mousemove', startBecauseMouseMoved);
|
||||
}
|
||||
|
||||
function movements (remove) {
|
||||
var op = remove ? 'remove' : 'add';
|
||||
touchy(documentElement, op, 'selectstart', preventGrabbed); // IE8
|
||||
touchy(documentElement, op, 'click', preventGrabbed);
|
||||
}
|
||||
|
||||
function destroy () {
|
||||
events(true);
|
||||
release({});
|
||||
}
|
||||
|
||||
function preventGrabbed (e) {
|
||||
if (_grabbed) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function grab (e) {
|
||||
_moveX = e.clientX;
|
||||
_moveY = e.clientY;
|
||||
|
||||
var ignore = whichMouseButton(e) !== 1 || e.metaKey || e.ctrlKey;
|
||||
if (ignore) {
|
||||
return; // we only care about honest-to-god left clicks and touch events
|
||||
}
|
||||
var item = e.target;
|
||||
var context = canStart(item);
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
_grabbed = context;
|
||||
eventualMovements();
|
||||
if (e.type === 'mousedown') {
|
||||
if (isInput(item)) { // see also: https://github.com/bevacqua/dragula/issues/208
|
||||
item.focus(); // fixes https://github.com/bevacqua/dragula/issues/176
|
||||
} else {
|
||||
e.preventDefault(); // fixes https://github.com/bevacqua/dragula/issues/155
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startBecauseMouseMoved (e) {
|
||||
if (!_grabbed) {
|
||||
return;
|
||||
}
|
||||
if (whichMouseButton(e) === 0) {
|
||||
release({});
|
||||
return; // when text is selected on an input and then dragged, mouseup doesn't fire. this is our only hope
|
||||
}
|
||||
if (e.clientX === _moveX && e.clientY === _moveY) {
|
||||
return;
|
||||
}
|
||||
if (o.ignoreInputTextSelection) {
|
||||
var clientX = getCoord('clientX', e);
|
||||
var clientY = getCoord('clientY', e);
|
||||
var elementBehindCursor = document.elementFromPoint(clientX, clientY);
|
||||
if (isInput(elementBehindCursor)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var grabbed = _grabbed; // call to end() unsets _grabbed
|
||||
eventualMovements(true);
|
||||
movements();
|
||||
end();
|
||||
start(grabbed);
|
||||
|
||||
var offset = getOffset(_item);
|
||||
_offsetX = getCoord('pageX', e) - offset.left;
|
||||
_offsetY = getCoord('pageY', e) - offset.top;
|
||||
|
||||
classes.add(_copy || _item, 'gu-transit');
|
||||
renderMirrorImage();
|
||||
drag(e);
|
||||
}
|
||||
|
||||
function canStart (item) {
|
||||
if (drake.dragging && _mirror) {
|
||||
return;
|
||||
}
|
||||
if (isContainer(item)) {
|
||||
return; // don't drag container itself
|
||||
}
|
||||
var handle = item;
|
||||
while (item.parentElement && isContainer(item.parentElement) === false) {
|
||||
if (o.invalid(item, handle)) {
|
||||
return;
|
||||
}
|
||||
item = item.parentElement; // drag target should be a top element
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
var source = item.parentElement;
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
if (o.invalid(item, handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var movable = o.moves(item, source, handle, nextEl(item));
|
||||
if (!movable) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
item: item,
|
||||
source: source
|
||||
};
|
||||
}
|
||||
|
||||
function manualStart (item) {
|
||||
var context = canStart(item);
|
||||
if (context) {
|
||||
start(context);
|
||||
}
|
||||
}
|
||||
|
||||
function start (context) {
|
||||
if (isCopy(context.item, context.source)) {
|
||||
_copy = context.item.cloneNode(true);
|
||||
drake.emit('cloned', _copy, context.item, 'copy');
|
||||
}
|
||||
|
||||
_source = context.source;
|
||||
_item = context.item;
|
||||
_initialSibling = _currentSibling = nextEl(context.item);
|
||||
|
||||
drake.dragging = true;
|
||||
drake.emit('drag', _item, _source);
|
||||
}
|
||||
|
||||
function invalidTarget () {
|
||||
return false;
|
||||
}
|
||||
|
||||
function end () {
|
||||
if (!drake.dragging) {
|
||||
return;
|
||||
}
|
||||
var item = _copy || _item;
|
||||
drop(item, item.parentElement);
|
||||
}
|
||||
|
||||
function ungrab () {
|
||||
_grabbed = false;
|
||||
eventualMovements(true);
|
||||
movements(true);
|
||||
}
|
||||
|
||||
function release (e) {
|
||||
ungrab();
|
||||
|
||||
if (!drake.dragging) {
|
||||
return;
|
||||
}
|
||||
var item = _copy || _item;
|
||||
var clientX = getCoord('clientX', e);
|
||||
var clientY = getCoord('clientY', e);
|
||||
var elementBehindCursor = getElementBehindPoint(_mirror, clientX, clientY);
|
||||
var dropTarget = findDropTarget(elementBehindCursor, clientX, clientY);
|
||||
if (dropTarget && ((_copy && o.copySortSource) || (!_copy || dropTarget !== _source))) {
|
||||
drop(item, dropTarget);
|
||||
} else if (o.removeOnSpill) {
|
||||
remove();
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
function drop (item, target) {
|
||||
var parent = item.parentElement;
|
||||
if (_copy && o.copySortSource && target === _source) {
|
||||
parent.removeChild(_item);
|
||||
}
|
||||
if (isInitialPlacement(target)) {
|
||||
drake.emit('cancel', item, _source, _source);
|
||||
} else {
|
||||
drake.emit('drop', item, target, _source, _currentSibling);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function remove () {
|
||||
if (!drake.dragging) {
|
||||
return;
|
||||
}
|
||||
var item = _copy || _item;
|
||||
var parent = item.parentElement;
|
||||
if (parent) {
|
||||
parent.removeChild(item);
|
||||
}
|
||||
drake.emit(_copy ? 'cancel' : 'remove', item, parent, _source);
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function cancel (revert) {
|
||||
if (!drake.dragging) {
|
||||
return;
|
||||
}
|
||||
var reverts = arguments.length > 0 ? revert : o.revertOnSpill;
|
||||
var item = _copy || _item;
|
||||
var parent = item.parentElement;
|
||||
if (parent === _source && _copy) {
|
||||
parent.removeChild(_copy);
|
||||
}
|
||||
var initial = isInitialPlacement(parent);
|
||||
if (initial === false && !_copy && reverts) {
|
||||
_source.insertBefore(item, _initialSibling);
|
||||
}
|
||||
if (initial || reverts) {
|
||||
drake.emit('cancel', item, _source, _source);
|
||||
} else {
|
||||
drake.emit('drop', item, parent, _source, _currentSibling);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function cleanup () {
|
||||
var item = _copy || _item;
|
||||
ungrab();
|
||||
removeMirrorImage();
|
||||
if (item) {
|
||||
classes.rm(item, 'gu-transit');
|
||||
}
|
||||
if (_renderTimer) {
|
||||
clearTimeout(_renderTimer);
|
||||
}
|
||||
drake.dragging = false;
|
||||
if (_lastDropTarget) {
|
||||
drake.emit('out', item, _lastDropTarget, _source);
|
||||
}
|
||||
drake.emit('dragend', item);
|
||||
_source = _item = _copy = _initialSibling = _currentSibling = _renderTimer = _lastDropTarget = null;
|
||||
}
|
||||
|
||||
function isInitialPlacement (target, s) {
|
||||
var sibling;
|
||||
if (s !== void 0) {
|
||||
sibling = s;
|
||||
} else if (_mirror) {
|
||||
sibling = _currentSibling;
|
||||
} else {
|
||||
sibling = nextEl(_copy || _item);
|
||||
}
|
||||
return target === _source && sibling === _initialSibling;
|
||||
}
|
||||
|
||||
function findDropTarget (elementBehindCursor, clientX, clientY) {
|
||||
var target = elementBehindCursor;
|
||||
while (target && !accepted()) {
|
||||
target = target.parentElement;
|
||||
}
|
||||
return target;
|
||||
|
||||
function accepted () {
|
||||
var droppable = isContainer(target);
|
||||
if (droppable === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var immediate = getImmediateChild(target, elementBehindCursor);
|
||||
var reference = getReference(target, immediate, clientX, clientY);
|
||||
var initial = isInitialPlacement(target, reference);
|
||||
if (initial) {
|
||||
return true; // should always be able to drop it right back where it was
|
||||
}
|
||||
return o.accepts(_item, target, _source, reference);
|
||||
}
|
||||
}
|
||||
|
||||
function drag (e) {
|
||||
if (!_mirror) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
var clientX = getCoord('clientX', e);
|
||||
var clientY = getCoord('clientY', e);
|
||||
var x = clientX - _offsetX;
|
||||
var y = clientY - _offsetY;
|
||||
|
||||
_mirror.style.left = x + 'px';
|
||||
_mirror.style.top = y + 'px';
|
||||
|
||||
var item = _copy || _item;
|
||||
var elementBehindCursor = getElementBehindPoint(_mirror, clientX, clientY);
|
||||
var dropTarget = findDropTarget(elementBehindCursor, clientX, clientY);
|
||||
var changed = dropTarget !== null && dropTarget !== _lastDropTarget;
|
||||
if (changed || dropTarget === null) {
|
||||
out();
|
||||
_lastDropTarget = dropTarget;
|
||||
over();
|
||||
}
|
||||
if (dropTarget === _source && _copy && !o.copySortSource) {
|
||||
if (item.parentElement) {
|
||||
item.parentElement.removeChild(item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
var reference;
|
||||
var immediate = getImmediateChild(dropTarget, elementBehindCursor);
|
||||
if (immediate !== null) {
|
||||
reference = getReference(dropTarget, immediate, clientX, clientY);
|
||||
} else if (o.revertOnSpill === true && !_copy) {
|
||||
reference = _initialSibling;
|
||||
dropTarget = _source;
|
||||
} else {
|
||||
if (_copy && item.parentElement) {
|
||||
item.parentElement.removeChild(item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (
|
||||
reference === null ||
|
||||
reference !== item &&
|
||||
reference !== nextEl(item) &&
|
||||
reference !== _currentSibling
|
||||
) {
|
||||
_currentSibling = reference;
|
||||
dropTarget.insertBefore(item, reference);
|
||||
drake.emit('shadow', item, dropTarget, _source);
|
||||
}
|
||||
function moved (type) { drake.emit(type, item, _lastDropTarget, _source); }
|
||||
function over () { if (changed) { moved('over'); } }
|
||||
function out () { if (_lastDropTarget) { moved('out'); } }
|
||||
}
|
||||
|
||||
function spillOver (el) {
|
||||
classes.rm(el, 'gu-hide');
|
||||
}
|
||||
|
||||
function spillOut (el) {
|
||||
if (drake.dragging) { classes.add(el, 'gu-hide'); }
|
||||
}
|
||||
|
||||
function renderMirrorImage () {
|
||||
if (_mirror) {
|
||||
return;
|
||||
}
|
||||
var rect = _item.getBoundingClientRect();
|
||||
_mirror = _item.cloneNode(true);
|
||||
_mirror.style.width = getRectWidth(rect) + 'px';
|
||||
_mirror.style.height = getRectHeight(rect) + 'px';
|
||||
classes.rm(_mirror, 'gu-transit');
|
||||
classes.add(_mirror, 'gu-mirror');
|
||||
o.mirrorContainer.appendChild(_mirror);
|
||||
touchy(documentElement, 'add', 'mousemove', drag);
|
||||
classes.add(o.mirrorContainer, 'gu-unselectable');
|
||||
drake.emit('cloned', _mirror, _item, 'mirror');
|
||||
}
|
||||
|
||||
function removeMirrorImage () {
|
||||
if (_mirror) {
|
||||
classes.rm(o.mirrorContainer, 'gu-unselectable');
|
||||
touchy(documentElement, 'remove', 'mousemove', drag);
|
||||
_mirror.parentElement.removeChild(_mirror);
|
||||
_mirror = null;
|
||||
}
|
||||
}
|
||||
|
||||
function getImmediateChild (dropTarget, target) {
|
||||
var immediate = target;
|
||||
while (immediate !== dropTarget && immediate.parentElement !== dropTarget) {
|
||||
immediate = immediate.parentElement;
|
||||
}
|
||||
if (immediate === documentElement) {
|
||||
return null;
|
||||
}
|
||||
return immediate;
|
||||
}
|
||||
|
||||
function getReference (dropTarget, target, x, y) {
|
||||
var horizontal = o.direction === 'horizontal';
|
||||
var reference = target !== dropTarget ? inside() : outside();
|
||||
return reference;
|
||||
|
||||
function outside () { // slower, but able to figure out any position
|
||||
var len = dropTarget.children.length;
|
||||
var i;
|
||||
var el;
|
||||
var rect;
|
||||
for (i = 0; i < len; i++) {
|
||||
el = dropTarget.children[i];
|
||||
rect = el.getBoundingClientRect();
|
||||
if (horizontal && rect.left > x) { return el; }
|
||||
if (!horizontal && rect.top > y) { return el; }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function inside () { // faster, but only available if dropped inside a child element
|
||||
var rect = target.getBoundingClientRect();
|
||||
if (horizontal) {
|
||||
return resolve(x > rect.left + getRectWidth(rect) / 2);
|
||||
}
|
||||
return resolve(y > rect.top + getRectHeight(rect) / 2);
|
||||
}
|
||||
|
||||
function resolve (after) {
|
||||
return after ? nextEl(target) : target;
|
||||
}
|
||||
}
|
||||
|
||||
function isCopy (item, container) {
|
||||
return typeof o.copy === 'boolean' ? o.copy : o.copy(item, container);
|
||||
}
|
||||
}
|
||||
|
||||
function touchy (el, op, type, fn) {
|
||||
var touch = {
|
||||
mouseup: 'touchend',
|
||||
mousedown: 'touchstart',
|
||||
mousemove: 'touchmove'
|
||||
};
|
||||
var microsoft = {
|
||||
mouseup: 'MSPointerUp',
|
||||
mousedown: 'MSPointerDown',
|
||||
mousemove: 'MSPointerMove'
|
||||
};
|
||||
if (global.navigator.msPointerEnabled) {
|
||||
crossvent[op](el, microsoft[type], fn);
|
||||
}
|
||||
crossvent[op](el, touch[type], fn);
|
||||
crossvent[op](el, type, fn);
|
||||
}
|
||||
|
||||
function whichMouseButton (e) {
|
||||
if (e.buttons !== void 0) { return e.buttons; }
|
||||
if (e.which !== void 0) { return e.which; }
|
||||
var button = e.button;
|
||||
if (button !== void 0) { // see https://github.com/jquery/jquery/blob/99e8ff1baa7ae341e94bb89c3e84570c7c3ad9ea/src/event.js#L573-L575
|
||||
return button & 1 ? 1 : button & 2 ? 3 : (button & 4 ? 2 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
function getOffset (el) {
|
||||
var rect = el.getBoundingClientRect();
|
||||
return {
|
||||
left: rect.left + getScroll('scrollLeft', 'pageXOffset'),
|
||||
top: rect.top + getScroll('scrollTop', 'pageYOffset')
|
||||
};
|
||||
}
|
||||
|
||||
function getScroll (scrollProp, offsetProp) {
|
||||
if (typeof global[offsetProp] !== 'undefined') {
|
||||
return global[offsetProp];
|
||||
}
|
||||
var documentElement = document.documentElement;
|
||||
if (documentElement.clientHeight) {
|
||||
return documentElement[scrollProp];
|
||||
}
|
||||
var body = document.body;
|
||||
return body[scrollProp];
|
||||
}
|
||||
|
||||
function getElementBehindPoint (point, x, y) {
|
||||
var p = point || {};
|
||||
var state = p.className;
|
||||
var el;
|
||||
p.className += ' gu-hide';
|
||||
el = document.elementFromPoint(x, y);
|
||||
p.className = state;
|
||||
return el;
|
||||
}
|
||||
|
||||
function never () { return false; }
|
||||
function always () { return true; }
|
||||
function getRectWidth (rect) { return rect.width || (rect.right - rect.left); }
|
||||
function getRectHeight (rect) { return rect.height || (rect.bottom - rect.top); }
|
||||
function isInput (el) { return el.tagName === 'INPUT' || el.tagName === 'TEXTAREA'; }
|
||||
|
||||
function nextEl (el) {
|
||||
return el.nextElementSibling || manually();
|
||||
function manually () {
|
||||
var sibling = el;
|
||||
do {
|
||||
sibling = sibling.nextSibling;
|
||||
} while (sibling && sibling.nodeType !== 1);
|
||||
return sibling;
|
||||
}
|
||||
}
|
||||
|
||||
function getEventHost (e) {
|
||||
// on touchend event, we have to use `e.changedTouches`
|
||||
// see http://stackoverflow.com/questions/7192563/touchend-event-properties
|
||||
// see https://github.com/bevacqua/dragula/issues/34
|
||||
if (e.targetTouches && e.targetTouches.length) {
|
||||
return e.targetTouches[0];
|
||||
}
|
||||
if (e.changedTouches && e.changedTouches.length) {
|
||||
return e.changedTouches[0];
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
function getCoord (coord, e) {
|
||||
var host = getEventHost(e);
|
||||
var missMap = {
|
||||
pageX: 'clientX', // IE8
|
||||
pageY: 'clientY' // IE8
|
||||
};
|
||||
if (coord in missMap && !(coord in host) && missMap[coord] in host) {
|
||||
coord = missMap[coord];
|
||||
}
|
||||
return host[coord];
|
||||
}
|
||||
|
||||
module.exports = dragula;
|
14
dashboard-ui/bower_components/dragula.js/dragula.styl
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
.gu-mirror
|
||||
position fixed !important
|
||||
margin 0 !important
|
||||
z-index 9999 !important
|
||||
opacity 0.8
|
||||
|
||||
.gu-hide
|
||||
display none !important
|
||||
|
||||
.gu-unselectable
|
||||
user-select none !important
|
||||
|
||||
.gu-transit
|
||||
opacity 0.2
|
194
dashboard-ui/bower_components/dragula.js/example/example.css
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
body {
|
||||
background-color: #942A57;
|
||||
margin: 0 auto;
|
||||
max-width: 760px;
|
||||
}
|
||||
|
||||
html, body {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*, *:before, *:after {
|
||||
-webkit-box-sizing: inherit;
|
||||
-moz-box-sizing: inherit;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body, input, button {
|
||||
font-family: Georgia, Helvetica;
|
||||
font-size: 17px;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
background-color: #AC5C7E;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
border-bottom: 5px solid #A13462;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
h3 div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
margin-top: 0;
|
||||
}
|
||||
.tagline-text {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.__slackin {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.promo {
|
||||
margin-bottom: 0;
|
||||
font-style: italic;
|
||||
padding: 10px;
|
||||
background-color: #ff4020;
|
||||
border-bottom: 5px solid #c00;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
a,
|
||||
a:hover {
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
pre code {
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
sub {
|
||||
display: block;
|
||||
text-align: right;
|
||||
margin-top: -10px;
|
||||
font-size: 11px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.parent {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
margin: 50px 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: #ecf0f1;
|
||||
padding: 10px;
|
||||
color: #942A57;
|
||||
border: 0;
|
||||
margin: 5px 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #ecf0f1;
|
||||
color: #942A57;
|
||||
border: 0;
|
||||
padding: 18px 12px;
|
||||
margin-left: 6px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #e74c3c;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
.gh-fork {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* dragula-specific example page styles */
|
||||
.wrapper {
|
||||
display: table;
|
||||
}
|
||||
.container {
|
||||
display: table-cell;
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
width: 50%;
|
||||
}
|
||||
.container:nth-child(odd) {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
/*
|
||||
* note that styling gu-mirror directly is a bad practice because it's too generic.
|
||||
* you're better off giving the draggable elements a unique class and styling that directly!
|
||||
*/
|
||||
.container > div,
|
||||
.gu-mirror {
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
transition: opacity 0.4s ease-in-out;
|
||||
}
|
||||
.container > div {
|
||||
cursor: move;
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
}
|
||||
.gu-mirror {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
}
|
||||
.container .ex-moved {
|
||||
background-color: #e74c3c;
|
||||
}
|
||||
.container.ex-over {
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
#left-lovehandles > div,
|
||||
#right-lovehandles > div {
|
||||
cursor: initial;
|
||||
}
|
||||
.handle {
|
||||
padding: 0 5px;
|
||||
margin-right: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
cursor: move;
|
||||
}
|
||||
.image-thing {
|
||||
margin: 20px 0;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
56
dashboard-ui/bower_components/dragula.js/example/example.js
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
var crossvent = require('crossvent');
|
||||
var sortable = $('sortable');
|
||||
|
||||
dragula([$('left-defaults'), $('right-defaults')]);
|
||||
dragula([$('left-copy'), $('right-copy')], { copy: true });
|
||||
dragula([$('left-events'), $('right-events')])
|
||||
.on('drag', function (el) {
|
||||
el.className = el.className.replace('ex-moved', '');
|
||||
})
|
||||
.on('drop', function (el) {
|
||||
el.className += ' ex-moved';
|
||||
})
|
||||
.on('over', function (el, container) {
|
||||
container.className += ' ex-over';
|
||||
})
|
||||
.on('out', function (el, container) {
|
||||
container.className = container.className.replace('ex-over', '');
|
||||
});
|
||||
dragula([$('left-rollbacks'), $('right-rollbacks')], { revertOnSpill: true });
|
||||
dragula([$('left-lovehandles'), $('right-lovehandles')], {
|
||||
moves: function (el, container, handle) {
|
||||
return handle.className === 'handle';
|
||||
}
|
||||
});
|
||||
|
||||
dragula([$('left-rm-spill'), $('right-rm-spill')], { removeOnSpill: true });
|
||||
dragula([$('left-copy-1tomany'), $('right-copy-1tomany')], {
|
||||
copy: function (el, source) {
|
||||
return source === $('left-copy-1tomany');
|
||||
},
|
||||
accepts: function (el, target) {
|
||||
return target !== $('left-copy-1tomany');
|
||||
}
|
||||
});
|
||||
|
||||
dragula([sortable]);
|
||||
|
||||
crossvent.add(sortable, 'click', clickHandler);
|
||||
|
||||
function clickHandler (e) {
|
||||
var target = e.target;
|
||||
if (target === sortable) {
|
||||
return;
|
||||
}
|
||||
target.innerHTML += ' [click!]';
|
||||
|
||||
setTimeout(function () {
|
||||
target.innerHTML = target.innerHTML.replace(/ \[click!\]/g, '');
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function $ (id) {
|
||||
return document.getElementById(id);
|
||||
}
|
237
dashboard-ui/bower_components/dragula.js/example/example.min.js
vendored
Normal file
BIN
dashboard-ui/bower_components/dragula.js/favicon.ico
vendored
Normal file
After Width: | Height: | Size: 32 KiB |
205
dashboard-ui/bower_components/dragula.js/index.html
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
<!doctype html>
|
||||
<meta charset='utf-8'>
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<link href='dist/dragula.css' rel='stylesheet' type='text/css' />
|
||||
<link href='example/example.css' rel='stylesheet' type='text/css' />
|
||||
<title>dragula</title>
|
||||
<h1><a href='https://github.com/bevacqua/dragula'><img src='resources/logo.svg' onerror='this.src="resources/logo.png"' alt='dragula'/></a></h1>
|
||||
<h3 class='tagline'><span class='tagline-text'>Drag and drop so simple it hurts</span><script async defer src='https://dragula-slackin.herokuapp.com/slackin.js'></script></h3>
|
||||
<a href='https://github.com/bevacqua/dragula'>
|
||||
<img class='gh-fork' src='https://camo.githubusercontent.com/52760788cde945287fbb584134c4cbc2bc36f904/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f77686974655f6666666666662e706e67' alt='Fork me on GitHub' data-canonical-src='https://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div class='examples'>
|
||||
<div class='parent'>
|
||||
<label for='hy'>Move stuff between these two containers. Note how the stuff gets inserted near the mouse pointer? Great stuff.</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-defaults' class='container'>
|
||||
<div>You can move these elements between these two containers</div>
|
||||
<div>Moving them anywhere else isn't quite possible</div>
|
||||
<div>Anything can be moved around. That includes images, <a href='https://github.com/bevacqua/dragula'>links</a>, or any other nested elements.
|
||||
<div class='image-thing'><img src='resources/icon.svg' onerror='this.src="resources/icon.png"' alt='dragula'/></div><sub>(You can still click on links, as usual!)</sub>
|
||||
</div>
|
||||
</div>
|
||||
<div id='right-defaults' class='container'>
|
||||
<div>There's also the possibility of moving elements around in the same container, changing their position</div>
|
||||
<div>This is the default use case. You only need to specify the containers you want to use</div>
|
||||
<div>More interactive use cases lie ahead</div>
|
||||
<div>Moving <code><input/></code> elements works just fine. You can still focus them, too. <input placeholder='See?' /></div>
|
||||
<div>Make sure to check out the <a href='https://github.com/bevacqua/dragula#readme'>documentation on GitHub!</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)]);
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>There are plenty of events along the lifetime of a drag event. Check out <a href='https://github.com/bevacqua/dragula#drakeon-events'>all of them</a> in the docs!</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-events' class='container'>
|
||||
<div>As soon as you start dragging an element, a <code>drag</code> event is fired</div>
|
||||
<div>Whenever an element is cloned because <code>copy: true</code>, a <code>cloned</code> event fires</div>
|
||||
<div>The <code>shadow</code> event fires whenever the placeholder showing where an element would be dropped is moved to a different container or position</div>
|
||||
<div>A <code>drop</code> event is fired whenever an element is dropped anywhere other than its origin <em>(where it was initially dragged from)</em></div>
|
||||
</div>
|
||||
<div id='right-events' class='container'>
|
||||
<div>If the element gets removed from the DOM as a result of dropping outside of any containers, a <code>remove</code> event gets fired</div>
|
||||
<div>A <code>cancel</code> event is fired when an element would be dropped onto an invalid target, but retains its original placement instead</div>
|
||||
<div>The <code>over</code> event fires when you drag something over a container, and <code>out</code> fires when you drag it away from the container</div>
|
||||
<div>Lastly, a <code>dragend</code> event is fired whenever a drag operation ends, regardless of whether it ends in a cancellation, removal, or drop</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)])
|
||||
.on('drag', function (el) {
|
||||
el.className = el.className.replace('ex-moved', '');
|
||||
}).on('drop', function (el) {
|
||||
el.className += ' ex-moved';
|
||||
}).on('over', function (el, container) {
|
||||
container.className += ' ex-over';
|
||||
}).on('out', function (el, container) {
|
||||
container.className = container.className.replace('ex-over', '');
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>Need to be able to quickly delete stuff when it spills out of the chosen containers? Note how you can easily sort the items in any containers by just dragging and dropping.</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-rm-spill' class='container'>
|
||||
<div>Anxious Cab Driver</div>
|
||||
<div>Thriving Venture</div>
|
||||
<div>Such <a href='http://ponyfoo.com'>a good blog</a></div>
|
||||
<div>Calm Clam</div>
|
||||
</div>
|
||||
<div id='right-rm-spill' class='container'>
|
||||
<div>Banana Boat</div>
|
||||
<div>Orange Juice</div>
|
||||
<div>Cuban Cigar</div>
|
||||
<div>Terrible Comedian</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(single)], {
|
||||
removeOnSpill: true
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>By default, dropping an element outside of any known containers will keep the element in the last place it went over. You can make elements go back to origin if they're dropped outside of known containers, too.</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-rollbacks' class='container'>
|
||||
<div>Moving items between containers works as usual</div>
|
||||
<div>If you try to drop an item outside of any containers, though, it'll retain its original position</div>
|
||||
<div>When that happens, a <code>cancel</code> event will be raised</div>
|
||||
</div>
|
||||
<div id='right-rollbacks' class='container'>
|
||||
<div>Note that the dragged element will go back to the place you originally dragged it from, even if you move it over other containers</div>
|
||||
<div>This is useful if you want to ensure drop events only happen when the user intends for them to happen explicitly, avoiding surprises</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)], {
|
||||
revertOnSpill: true
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>Copying stuff is common too, so we made it easy for you.</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-copy' class='container'>
|
||||
<div>When elements are copyable, they can't be sorted in their origin container</div>
|
||||
<div>Copying prevents original elements from being dragged. A copy gets created and <em>that</em> gets dragged instead</div>
|
||||
<div>Whenever that happens, a <code>cloned</code> event is raised</div>
|
||||
</div>
|
||||
<div id='right-copy' class='container'>
|
||||
<div>Note that the clones get destroyed if they're not dropped into another container</div>
|
||||
<div>You'll be dragging a copy, so when they're dropped into another container you'll see the duplication.</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)], {
|
||||
copy: true
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>Copying stuff from only one of the containers and sorting on the other one? No problem!</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-copy-1tomany' class='container'>
|
||||
<div>When elements are copyable, they can't be sorted in their origin container</div>
|
||||
<div>Copying prevents original elements from being dragged. A copy gets created and <em>that</em> gets dragged instead</div>
|
||||
<div>Whenever that happens, a <code>cloned</code> event is raised</div>
|
||||
<div>Note that the clones get destroyed if they're not dropped into another container</div>
|
||||
<div>You'll be dragging a copy, so when they're dropped into another container you'll see the duplication.</div>
|
||||
</div>
|
||||
<div id='right-copy-1tomany' class='container'>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)], {
|
||||
copy: function (el, source) {
|
||||
return source === left
|
||||
},
|
||||
accepts: function (el, target) {
|
||||
return target !== left
|
||||
}
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label for='hy'>Drag handles float your cruise?</label>
|
||||
<div class='wrapper'>
|
||||
<div id='left-lovehandles' class='container'>
|
||||
<div><span class='handle'>+</span>Move me, but you can use the plus sign to drag me around.</div>
|
||||
<div><span class='handle'>+</span>Note that <code>handle</code> element in the <code>moves</code> handler is just the original event target.</div>
|
||||
</div>
|
||||
<div id='right-lovehandles' class='container'>
|
||||
<div><span class='handle'>+</span>This might also be useful if you want multiple children of an element to be able to trigger a drag event.</div>
|
||||
<div><span class='handle'>+</span>You can also use the <code>moves</code> option to determine whether an element can be dragged at all from a container, <em>drag handle or not</em>.</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(left), document.getElementById(right)], {
|
||||
moves: function (el, container, handle) {
|
||||
return handle.className === 'handle';
|
||||
}
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
<div>There are a few similar mechanisms to determine whether an element can be dragged from a certain container <a href='https://github.com/bevacqua/dragula#optionsmoves'>(<code>moves</code>)</a>, whether an element can be dropped into a certain container at a certain position <a href='https://github.com/bevacqua/dragula#optionsaccepts'>(<code>accepts</code>)</a>, and whether an element is able to originate a drag event <a href='https://github.com/bevacqua/dragula#optionsinvalid'>(<code>invalid</code>)</a>.</div>
|
||||
</div>
|
||||
<div class='parent'>
|
||||
<label><strong>Click or Drag!</strong> Fires a click when the mouse button is released before a <code>mousemove</code> event, otherwise a drag event is fired. No extra configuration is necessary.</label>
|
||||
<div class='wrapper'>
|
||||
<div id='sortable' class='container'>
|
||||
<div>Clicking on these elements triggers a regular <code>click</code> event you can listen to.</div>
|
||||
<div>Try dragging or clicking on this element.</div>
|
||||
<div>Note how you can click normally?</div>
|
||||
<div>Drags don't trigger click events.</div>
|
||||
<div>Clicks don't end up in a drag, either.</div>
|
||||
<div>This is useful if you have elements that can be both clicked or dragged.</div>
|
||||
</div>
|
||||
</div>
|
||||
<pre>
|
||||
<code>
|
||||
dragula([document.getElementById(container)]);
|
||||
</code>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class='promo'>Who couldn't love a pun that good? — <a href='http://thenextweb.com/dd/2015/07/20/less-of-a-drag-maaaaaaaan'>The Next Web</a></h3>
|
||||
<h3>Get it on GitHub! <a href='https://github.com/bevacqua/dragula'>bevacqua/dragula</a></h3>
|
||||
<script src='dist/dragula.js'></script>
|
||||
<script src='example/example.min.js'></script>
|
20
dashboard-ui/bower_components/dragula.js/license
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2015 Nicolas Bevacqua
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
72
dashboard-ui/bower_components/dragula.js/package.json
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"name": "dragula",
|
||||
"version": "3.5.1",
|
||||
"description": "Drag and drop so simple it hurts",
|
||||
"main": "dragula.js",
|
||||
"scripts": {
|
||||
"build": "npm run scripts && npm run styles",
|
||||
"deploy": "npm run build && npm run deployment && npm run sync",
|
||||
"deploy-plugins": "npm run deploy-react ; npm run deploy-angular ; cd ../dragula",
|
||||
"deploy-react": "cd ../react-dragula ; npm i -S dragula@* ; git commit package.json -m 'bumped dragula version'; npm run deploy",
|
||||
"deploy-angular": "cd ../angular-dragula ; npm i -S dragula@* ; git commit package.json -m 'bumped dragula version'; npm run deploy",
|
||||
"deployment": "git add dist && npm version ${BUMP:-\"patch\"} --no-git-tag-version && git add package.json && git commit -am \"Autogenerated pre-deployment commit\" && bower version ${BUMP:-\"patch\"} && git reset HEAD~2 && git add . && git commit -am \"Release $(cat package.json | jq -r .version)\" && git push --tags && npm publish && git push",
|
||||
"scripts": "jshint . && browserify -s dragula -do dist/dragula.js dragula.js && uglifyjs -m -c -o dist/dragula.min.js dist/dragula.js",
|
||||
"start": "watchify -dvo example/example.min.js example/example.js & watchify -dvs dragula -o dist/dragula.js dragula.js & stylus -w dragula.styl --import node_modules/nib -o dist",
|
||||
"styles": "stylus dragula.styl --import node_modules/nib -o dist && cleancss dist/dragula.css -o dist/dragula.min.css",
|
||||
"sync": "git checkout gh-pages ; git merge master ; git push ; git checkout master",
|
||||
"lint": "jshint . --reporter node_modules/jshint-stylish/index.js",
|
||||
"codestyle": "xo",
|
||||
"test": "npm run lint && npm run codestyle && browserify test/*.js | testron",
|
||||
"test-watch": "hihat test/*.js -p tap-dev-tool"
|
||||
},
|
||||
"xo": {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"space": true,
|
||||
"ignores": [
|
||||
"dist/**"
|
||||
],
|
||||
"rules": {
|
||||
"consistent-return": 0,
|
||||
"no-void": 0,
|
||||
"no-inline-comments": 0,
|
||||
"object-curly-spacing": 0,
|
||||
"space-before-function-paren": 0,
|
||||
"no-undef": 0,
|
||||
"brace-style": 0
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bevacqua/dragula.git"
|
||||
},
|
||||
"author": "Nicolas Bevacqua <nicolasbevacqua@gmail.com> (http://bevacqua.io/)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bevacqua/dragula/issues"
|
||||
},
|
||||
"homepage": "https://github.com/bevacqua/dragula",
|
||||
"dependencies": {
|
||||
"contra": "1.9.1",
|
||||
"crossvent": "1.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bower": "1.5.2",
|
||||
"browserify": "11.0.0",
|
||||
"clean-css": "3.3.6",
|
||||
"electron-prebuilt": "0.30.1",
|
||||
"hihat": "1.2.1",
|
||||
"jshint": "2.8.0",
|
||||
"jshint-stylish": "2.0.1",
|
||||
"nib": "1.1.0",
|
||||
"stylus": "0.52.0",
|
||||
"tap-dev-tool": "1.3.0",
|
||||
"tape": "4.0.1",
|
||||
"testron": "1.2.0",
|
||||
"uglify-js": "2.4.24",
|
||||
"watchify": "3.3.0",
|
||||
"xo": "0.7.1"
|
||||
}
|
||||
}
|
314
dashboard-ui/bower_components/dragula.js/readme.markdown
vendored
Normal file
|
@ -0,0 +1,314 @@
|
|||
[![logo.png][3]][2]
|
||||
|
||||
[![Travis CI][5]][4] [![Slack Status][17]][18] [![Flattr][6]][7] [![Patreon][19]][20]
|
||||
|
||||
> Drag and drop so simple it hurts
|
||||
|
||||
Browser support includes every sane browser and **IE7+**. <sub>_(Granted you polyfill the functional `Array` methods in ES5)_</sub>
|
||||
|
||||
Framework support includes vanilla JavaScript, Angular, and React.
|
||||
|
||||
- Official [Angular bridge][8] for `dragula` [_(demo)_][10]
|
||||
- Official [React bridge][9] for `dragula` [_(demo)_][11]
|
||||
|
||||
# Demo
|
||||
|
||||
[![demo.png][1]][2]
|
||||
|
||||
Try out the [demo][2]!
|
||||
|
||||
# Inspiration
|
||||
|
||||
Have you ever wanted a drag and drop library that just works? That doesn't just depend on bloated frameworks, that has great support? That actually understands where to place the elements when they are dropped? That doesn't need you to do a zillion things to get it to work? Well, so did I!
|
||||
|
||||
# Features
|
||||
|
||||
- Super easy to set up
|
||||
- No bloated dependencies
|
||||
- **Figures out sort order** on its own
|
||||
- A shadow where the item would be dropped offers **visual feedback**
|
||||
- Touch events!
|
||||
- Seamlessly handles clicks *without any configuration*
|
||||
|
||||
# Install
|
||||
|
||||
You can get it on npm.
|
||||
|
||||
```shell
|
||||
npm install dragula --save
|
||||
```
|
||||
|
||||
Or bower, too.
|
||||
|
||||
```shell
|
||||
bower install dragula --save
|
||||
```
|
||||
|
||||
If you're not using either package manager, you can use `dragula` by downloading the [files in the `dist` folder][15]. We **strongly suggest** using `npm`, though.
|
||||
|
||||
##### Including the CSS!
|
||||
|
||||
There's [a few CSS styles][16] you need to incorporate in order for `dragula` to work as expected.
|
||||
|
||||
You can add them by including [`dist/dragula.css`][12] or [`dist/dragula.min.css`][13] in your document. If you're using Stylus, you can include the styles using the directive below.
|
||||
|
||||
```styl
|
||||
@import 'node_modules/dragula/dragula'
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
Dragula provides the easiest possible API to make drag and drop a breeze in your applications.
|
||||
|
||||
## `dragula(containers?, options?)`
|
||||
|
||||
By default, `dragula` will allow the user to drag an element in any of the `containers` and drop it in any other container in the list. If the element is dropped anywhere that's not one of the `containers`, the event will be gracefully cancelled according to the `revertOnSpill` and `removeOnSpill` options.
|
||||
|
||||
Note that dragging is only triggered on left clicks, and only if no meta keys are pressed.
|
||||
|
||||
The example below allows the user to drag elements from `left` into `right`, and from `right` into `left`.
|
||||
|
||||
```js
|
||||
dragula([document.querySelector('#left'), document.querySelector('#right')]);
|
||||
```
|
||||
|
||||
You can also provide an `options` object. Here's an **overview of the default values**.
|
||||
|
||||
```js
|
||||
dragula(containers, {
|
||||
isContainer: function (el) {
|
||||
return false; // only elements in drake.containers will be taken into account
|
||||
},
|
||||
moves: function (el, source, handle, sibling) {
|
||||
return true; // elements are always draggable by default
|
||||
},
|
||||
accepts: function (el, target, source, sibling) {
|
||||
return true; // elements can be dropped in any of the `containers` by default
|
||||
},
|
||||
invalid: function (el, target) {
|
||||
return false; // don't prevent any drags from initiating by default
|
||||
},
|
||||
direction: 'vertical', // Y axis is considered when determining where an element would be dropped
|
||||
copy: false, // elements are moved by default, not copied
|
||||
copySortSource: false, // elements are moved by default, not copied
|
||||
revertOnSpill: false, // spilling will put the element back where it was dragged from, if this is true
|
||||
removeOnSpill: false, // spilling will `.remove` the element, if this is true
|
||||
mirrorContainer: document.body, // set the element that gets mirror elements appended
|
||||
ignoreInputTextSelection: true // allows users to select input text, see details below
|
||||
});
|
||||
```
|
||||
|
||||
You can omit the `containers` argument and add containers dynamically later on.
|
||||
|
||||
```js
|
||||
var drake = dragula({
|
||||
copy: true
|
||||
});
|
||||
drake.containers.push(container);
|
||||
```
|
||||
|
||||
You can also set the `containers` from the `options` object.
|
||||
|
||||
```js
|
||||
var drake = dragula({ containers: containers });
|
||||
```
|
||||
|
||||
And you could also not set any arguments, which defaults to a drake without containers and with the default options.
|
||||
|
||||
```js
|
||||
var drake = dragula();
|
||||
```
|
||||
|
||||
The options are detailed below.
|
||||
|
||||
#### `options.containers`
|
||||
|
||||
Setting this option is effectively the same as passing the containers in the first argument to `dragula(containers, options)`.
|
||||
|
||||
#### `options.isContainer`
|
||||
|
||||
Besides the containers that you pass to `dragula`, or the containers you dynamically `push` or `unshift` from [drake.containers](#drakecontainers), you can also use this method to specify any sort of logic that defines what is a container for this particular `drake` instance.
|
||||
|
||||
The example below dynamically treats all DOM elements with a CSS class of `dragula-container` as dragula containers for this `drake`.
|
||||
|
||||
```js
|
||||
var drake = dragula({
|
||||
isContainer: function (el) {
|
||||
return el.classList.contains('dragula-container');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
#### `options.moves`
|
||||
|
||||
You can define a `moves` method which will be invoked with `(el, source, handle, sibling)` whenever an element is clicked. If this method returns `false`, a drag event won't begin, and the event won't be prevented either. The `handle` element will be the original click target, which comes in handy to test if that element is an expected _"drag handle"_.
|
||||
|
||||
#### `options.accepts`
|
||||
|
||||
You can set `accepts` to a method with the following signature: `(el, target, source, sibling)`. It'll be called to make sure that an element `el`, that came from container `source`, can be dropped on container `target` before a `sibling` element. The `sibling` can be `null`, which would mean that the element would be placed as the last element in the container. Note that if `options.copy` is set to `true`, `el` will be set to the copy, instead of the originally dragged element.
|
||||
|
||||
Also note that **the position where a drag starts is always going to be a valid place where to drop the element**, even if `accepts` returned `false` for all cases.
|
||||
|
||||
#### `options.copy`
|
||||
|
||||
If `copy` is set to `true` _(or a method that returns `true`)_, items will be copied rather than moved. This implies the following differences:
|
||||
|
||||
Event | Move | Copy
|
||||
----------|------------------------------------------|---------------------------------------------
|
||||
`drag` | Element will be concealed from `source` | Nothing happens
|
||||
`drop` | Element will be moved into `target` | Element will be cloned into `target`
|
||||
`remove` | Element will be removed from DOM | Nothing happens
|
||||
`cancel` | Element will stay in `source` | Nothing happens
|
||||
|
||||
If a method is passed, it'll be called whenever an element starts being dragged in order to decide whether it should follow `copy` behavior or not. Consider the following example.
|
||||
|
||||
```js
|
||||
copy: function (el, source) {
|
||||
return el.className === 'you-may-copy-us';
|
||||
}
|
||||
```
|
||||
#### `options.copySortSource`
|
||||
|
||||
If `copy` is set to `true` _(or a method that returns `true`)_ and `copySortSource` is `true` as well, users will be able to sort elements in `copy`-source containers.
|
||||
|
||||
```js
|
||||
copy: true,
|
||||
copySortSource: true
|
||||
```
|
||||
|
||||
#### `options.revertOnSpill`
|
||||
|
||||
By default, spilling an element outside of any containers will move the element back to the _drop position previewed by the feedback shadow_. Setting `revertOnSpill` to `true` will ensure elements dropped outside of any approved containers are moved back to the source element where the drag event began, rather than stay at the _drop position previewed by the feedback shadow_.
|
||||
|
||||
#### `options.removeOnSpill`
|
||||
|
||||
By default, spilling an element outside of any containers will move the element back to the _drop position previewed by the feedback shadow_. Setting `removeOnSpill` to `true` will ensure elements dropped outside of any approved containers are removed from the DOM. Note that `remove` events won't fire if `copy` is set to `true`.
|
||||
|
||||
#### `options.direction`
|
||||
|
||||
When an element is dropped onto a container, it'll be placed near the point where the mouse was released. If the `direction` is `'vertical'`, the default value, the Y axis will be considered. Otherwise, if the `direction` is `'horizontal'`, the X axis will be considered.
|
||||
|
||||
#### `options.invalid`
|
||||
|
||||
You can provide an `invalid` method with a `(el, target)` signature. This method should return `true` for elements that shouldn't trigger a drag. Here's the default implementation, which doesn't prevent any drags.
|
||||
|
||||
```js
|
||||
function invalidTarget (el, target) {
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
Note that `invalid` will be invoked on the DOM element that was clicked and every parent up to immediate children of a `drake` container.
|
||||
|
||||
As an example, you could set `invalid` to return `false` whenever the clicked element _(or any of its parents)_ is an anchor tag.
|
||||
|
||||
```js
|
||||
invalid: function (el) {
|
||||
return el.tagName === 'A';
|
||||
}
|
||||
```
|
||||
|
||||
#### `options.mirrorContainer`
|
||||
|
||||
The DOM element where the mirror element displayed while dragging will be appended to. Defaults to `document.body`.
|
||||
|
||||
#### `options.ignoreInputTextSelection`
|
||||
|
||||
When this option is enabled, if the user clicks on an input element the drag won't start until their mouse pointer exits the input. This translates into the user being able to select text in inputs contained inside draggable elements, and still drag the element by moving their mouse outside of the input -- so you get the best of both worlds.
|
||||
|
||||
This option is enabled by default. Turn it off by setting it to `false`. If its disabled your users won't be able to select text in inputs within `dragula` containers with their mouse.
|
||||
|
||||
## API
|
||||
|
||||
The `dragula` method returns a tiny object with a concise API. We'll refer to the API returned by `dragula` as `drake`.
|
||||
|
||||
#### `drake.containers`
|
||||
|
||||
This property contains the collection of containers that was passed to `dragula` when building this `drake` instance. You can `push` more containers and `splice` old containers at will.
|
||||
|
||||
#### `drake.dragging`
|
||||
|
||||
This property will be `true` whenever an element is being dragged.
|
||||
|
||||
#### `drake.start(item)`
|
||||
|
||||
Enter drag mode **without a shadow**. This method is most useful when providing complementary keyboard shortcuts to an existing drag and drop solution. Even though a shadow won't be created at first, the user will get one as soon as they click on `item` and start dragging it around. Note that if they click and drag something else, `.end` will be called before picking up the new item.
|
||||
|
||||
#### `drake.end()`
|
||||
|
||||
Gracefully end the drag event as if using **the last position marked by the preview shadow** as the drop target. The proper `cancel` or `drop` event will be fired, depending on whether the item was dropped back where it was originally lifted from _(which is essentially a no-op that's treated as a `cancel` event)_.
|
||||
|
||||
#### `drake.cancel(revert)`
|
||||
|
||||
If an element managed by `drake` is currently being dragged, this method will gracefully cancel the drag action. You can also pass in `revert` at the method invocation level, effectively producing the same result as if `revertOnSpill` was `true`.
|
||||
|
||||
Note that **a _"cancellation"_ will result in a `cancel` event** only in the following scenarios.
|
||||
|
||||
- `revertOnSpill` is `true`
|
||||
- Drop target _(as previewed by the feedback shadow)_ is the source container **and** the item is dropped in the same position where it was originally dragged from
|
||||
|
||||
#### `drake.remove()`
|
||||
|
||||
If an element managed by `drake` is currently being dragged, this method will gracefully remove it from the DOM.
|
||||
|
||||
#### `drake.on` _(Events)_
|
||||
|
||||
The `drake` is an event emitter. The following events can be tracked using `drake.on(type, listener)`:
|
||||
|
||||
Event Name | Listener Arguments | Event Description
|
||||
-----------|----------------------------------|-------------------------------------------------------------------------------------
|
||||
`drag` | `el, source` | `el` was lifted from `source`
|
||||
`dragend` | `el` | Dragging event for `el` ended with either `cancel`, `remove`, or `drop`
|
||||
`drop` | `el, target, source, sibling` | `el` was dropped into `target` before a `sibling` element, and originally came from `source`
|
||||
`cancel` | `el, container, source` | `el` was being dragged but it got nowhere and went back into `container`, its last stable parent; `el` originally came from `source`
|
||||
`remove` | `el, container, source` | `el` was being dragged but it got nowhere and it was removed from the DOM. Its last stable parent was `container`, and originally came from `source`
|
||||
`shadow` | `el, container, source` | `el`, _the visual aid shadow_, was moved into `container`. May trigger many times as the position of `el` changes, even within the same `container`; `el` originally came from `source`
|
||||
`over` | `el, container, source` | `el` is over `container`, and originally came from `source`
|
||||
`out` | `el, container, source` | `el` was dragged out of `container` or dropped, and originally came from `source`
|
||||
`cloned` | `clone, original, type` | DOM element `original` was cloned as `clone`, of `type` _(`'mirror'` or `'copy'`)_. Fired for mirror images and when `copy: true`
|
||||
|
||||
#### `drake.destroy()`
|
||||
|
||||
Removes all drag and drop events used by `dragula` to manage drag and drop between the `containers`. If `.destroy` is called while an element is being dragged, the drag will be effectively cancelled.
|
||||
|
||||
## CSS
|
||||
|
||||
Dragula uses only four CSS classes. Their purpose is quickly explained below, but you can check [`dist/dragula.css`][12] to see the corresponding CSS rules.
|
||||
|
||||
- `gu-unselectable` is added to the `mirrorContainer` element when dragging. You can use it to style the `mirrorContainer` while something is being dragged.
|
||||
- `gu-transit` is added to the source element when its mirror image is dragged. It just adds opacity to it.
|
||||
- `gu-mirror` is added to the mirror image. It handles fixed positioning and `z-index` _(and removes any prior margins on the element)_. Note that the mirror image is appended to the `mirrorContainer`, not to its initial container. Keep that in mind when styling your elements with nested rules, like `.list .item { padding: 10px; }`.
|
||||
- `gu-hide` is a helper class to apply `display: none` to an element.
|
||||
|
||||
# Contributing
|
||||
|
||||
See [contributing.markdown][14] for details.
|
||||
|
||||
# Support
|
||||
|
||||
There's now a dedicated support channel in Slack. Visit the `dragula` [demo page][2] to get an invite. Support requests won't be handled through the repository anymore.
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
|
||||
[1]: https://github.com/bevacqua/dragula/blob/master/resources/demo.png
|
||||
[2]: http://bevacqua.github.io/dragula/
|
||||
[3]: https://github.com/bevacqua/dragula/blob/master/resources/logo.png
|
||||
[4]: https://travis-ci.org/bevacqua/dragula
|
||||
[5]: https://travis-ci.org/bevacqua/dragula.svg
|
||||
[6]: http://api.flattr.com/button/flattr-badge-large.png
|
||||
[7]: http://flattr.com/thing/4127996/bevacquadragula-on-GitHub
|
||||
[8]: https://github.com/bevacqua/angular-dragula
|
||||
[9]: https://github.com/bevacqua/react-dragula
|
||||
[10]: http://bevacqua.github.io/angular-dragula/
|
||||
[11]: http://bevacqua.github.io/react-dragula/
|
||||
[12]: https://github.com/bevacqua/dragula/blob/master/dist/dragula.css
|
||||
[13]: https://github.com/bevacqua/dragula/blob/master/dist/dragula.min.css
|
||||
[14]: https://github.com/bevacqua/dragula/blob/master/contributing.markdown
|
||||
[15]: https://github.com/bevacqua/dragula/blob/master/dist
|
||||
[16]: #css
|
||||
[17]: https://dragula-slackin.herokuapp.com/badge.svg
|
||||
[18]: https://bevacqua.github.io/dragula/
|
||||
[19]: https://rawgit.com/bevacqua/dragula/master/resources/patreon.svg
|
||||
[20]: https://patreon.com/bevacqua
|
BIN
dashboard-ui/bower_components/dragula.js/resources/demo.png
vendored
Normal file
After Width: | Height: | Size: 499 KiB |
BIN
dashboard-ui/bower_components/dragula.js/resources/eyes.png
vendored
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
dashboard-ui/bower_components/dragula.js/resources/icon.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
1
dashboard-ui/bower_components/dragula.js/resources/icon.svg
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="200" height="220" viewBox="0 0 200 220"><path fill="#961914" stroke="#52100F" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" d="M45.09 158.663c-2.652 40.673-7.848 34.5-7.797 43.87.05 9.37 8.36 9.02 8.36 9.02s8.315.26 8.265-9.11c-.064-11.833-5.916-5.496-8.827-43.78z"/><path fill="#221C3B" d="M161.298 129.555c-.584-.182-32.122-10.11-68.73-26.774l28.113-10.01c.815-.29 1.35-1.07 1.33-1.934-.02-.864-.596-1.617-1.423-1.865-.852-.255-85.436-26.222-107.022-77.88-.366-.877-1.3-1.374-2.23-1.19-.934.183-1.608.997-1.615 1.948-.15 21.842 9.604 43.05 28.337 61.876C25.045 65.42 13.063 56.408 3.41 46.828c-.66-.655-1.68-.77-2.466-.278-.787.49-1.134 1.456-.84 2.335 15.855 47.184 75.654 67.73 78.192 68.582.083.028.168.05.254.067l81.773 15.895c.128.024.256.036.383.036.9 0 1.71-.61 1.938-1.512.258-1.03-.332-2.083-1.346-2.4z"/><path fill="#952A58" d="M20.208 33.882C41.114 63.294 88.69 88.366 88.69 88.366l-5.67 11.54S28.464 66.843 20.207 33.883z"/><path fill="#221C3B" d="M176.817 96.7C169.673 82.777 156 73.51 136.173 69.153 81.2 57.076 66.583 46.878 38.43.955c-.473-.77-1.4-1.128-2.268-.874-.866.254-1.456 1.057-1.438 1.96.192 9.995 4.417 22.933 9.31 37.913 11.585 35.473 26.002 79.622-.626 117.455-.03.04-.057.083-.083.127-.157.258-.25.543-.28.832v.008c-.008.095-.01.19-.007.283v.008c.018.38.145.757.378 1.08.71.985 1.82 2.365 3.222 4.11 6.98 8.69 23.325 29.04 20.575 41.56-.212.967.316 1.944 1.242 2.297.233.09.474.13.71.13.707 0 1.383-.374 1.746-1.02 8.72-15.55 27.214-18.688 46.793-22.01 25.645-4.35 54.71-9.282 62.648-45.41 3.605-16.406 2.383-31.173-3.533-42.703zM80.36 118.05c9.852 2.812 31.804 9.922 32.124 24.504-15.71 4.128-28.223 7.467-41.418 19.84-3.02-1.093-11.167-3.906-18.468-5.194 14.872-8.625 23.905-24.973 27.76-39.15z"/><path fill="#952A58" d="M47.667 26.33c21.25 33.75 42.806 41.29 80.186 49.5 36.266 7.97 48.95 32.165 42.857 59.904-11.654 53.044-78.047 28.823-100.376 56.015-9.748-24.576-25.298-33.18-25.298-33.18s18.36 6.14 24.6 13.206c2.698 3.055 3.915 6.678 3.948 7.22 1.417 1-.43-5.054.34-5.968 21.34-25.367 55.016-14.355 60.676-40.12 7.2-32.77-34.33-29.798-59.6-42.625-5.08 31.65-10.715 48.995-29.964 68.287 21.16-21.657 22.518-60.586 14.408-99.74 21.733 28.916 53.058 34.035 69.974 37.75-37.017-11.142-66.5-29.685-81.75-70.25z"/></svg>
|
After Width: | Height: | Size: 2.3 KiB |
BIN
dashboard-ui/bower_components/dragula.js/resources/logo.png
vendored
Normal file
After Width: | Height: | Size: 25 KiB |
1
dashboard-ui/bower_components/dragula.js/resources/logo.svg
vendored
Normal file
After Width: | Height: | Size: 8.4 KiB |
1
dashboard-ui/bower_components/dragula.js/resources/patreon.svg
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="-2,0,65,65" color="#ff5900"><path d="M8 31.3C8 20.1 17.1 9.6 29.1 8.1c8.6-1 15.1 2.3 19.6 6.6 4.2 4 6.7 9.1 7.3 15.1 0.5 6-0.8 11.2-4.3 16.1-3.5 4.8-10.4 10.1-19 10.1l-11.7 0 0-23.1c0.1-5.1 1.8-9.5 8-11.6 5.4-1.6 11.7 1.4 13.6 7.1 2 6.1-0.9 10.2-4.3 12.7-3.4 2.5-8.7 2.5-12.2 0.1l0 7.9c2.3 1.1 5.2 1.4 7.3 1.3 7.6-1.1 13.5-5.4 16-11.9 2.6-6.9 0.8-14.9-4.6-19.9-6.5-5.3-13.6-6.6-21.2-2.9-5.3 2.7-9 8.2-9.9 14.2l0 26.1-5.6 0z" fill="#ff5900"/></svg>
|
After Width: | Height: | Size: 520 B |
108
dashboard-ui/bower_components/dragula.js/test/cancel.js
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('cancel does not throw when not dragging', function (t) {
|
||||
t.test('a single time', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.cancel();
|
||||
}, 'dragula ignores a single call to drake.cancel');
|
||||
st.end();
|
||||
});
|
||||
t.test('multiple times', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.cancel();
|
||||
drake.cancel();
|
||||
drake.cancel();
|
||||
drake.cancel();
|
||||
}, 'dragula ignores multiple calls to drake.cancel');
|
||||
st.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and cancel gets called, nothing happens', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.cancel();
|
||||
t.equal(div.children.length, 1, 'nothing happens');
|
||||
t.equal(drake.dragging, false, 'drake has stopped dragging');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and cancel gets called, cancel event is emitted', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('dragend', dragend);
|
||||
drake.cancel();
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function cancel (target, container) {
|
||||
t.equal(target, item, 'cancel was invoked with item');
|
||||
t.equal(container, div, 'cancel was invoked with container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and cancel gets called, default does not revert', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item);
|
||||
div2.appendChild(item);
|
||||
drake.on('drop', drop);
|
||||
drake.on('dragend', dragend);
|
||||
drake.cancel();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function drop (target, parent, source) {
|
||||
t.equal(target, item, 'drop was invoked with item');
|
||||
t.equal(parent, div2, 'drop was invoked with final container');
|
||||
t.equal(source, div, 'drop was invoked with source container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and cancel gets called, revert is executed', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item);
|
||||
div2.appendChild(item);
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('dragend', dragend);
|
||||
drake.cancel(true);
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function cancel (target, container) {
|
||||
t.equal(target, item, 'cancel was invoked with item');
|
||||
t.equal(container, div, 'cancel was invoked with container');
|
||||
}
|
||||
});
|
65
dashboard-ui/bower_components/dragula.js/test/classes.js
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var classes = require('../classes');
|
||||
|
||||
test('classes exports the expected api', function (t) {
|
||||
t.equal(typeof classes.add, 'function', 'classes.add is a method');
|
||||
t.equal(typeof classes.rm, 'function', 'classes.rm is a method');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can add a class', function (t) {
|
||||
var el = document.createElement('div');
|
||||
classes.add(el, 'gu-foo');
|
||||
t.equal(el.className, 'gu-foo', 'setting a class works');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can add a class to an element that already has classes', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'bar';
|
||||
classes.add(el, 'gu-foo');
|
||||
t.equal(el.className, 'bar gu-foo', 'appending a class works');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes.add is a no-op if class already is in element', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'gu-foo';
|
||||
classes.add(el, 'gu-foo');
|
||||
t.equal(el.className, 'gu-foo', 'no-op as expected');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can remove a class', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'gu-foo';
|
||||
classes.rm(el, 'gu-foo');
|
||||
t.equal(el.className, '', 'removing a class works');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can remove a class from a list on the right', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'bar gu-foo';
|
||||
classes.rm(el, 'gu-foo');
|
||||
t.equal(el.className, 'bar', 'removing a class from the list works to the right');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can remove a class from a list on the left', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'gu-foo bar';
|
||||
classes.rm(el, 'gu-foo');
|
||||
t.equal(el.className, 'bar', 'removing a class from the list works to the left');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('classes can remove a class from a list on the middle', function (t) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'foo gu-foo bar';
|
||||
classes.rm(el, 'gu-foo');
|
||||
t.equal(el.className, 'foo bar', 'removing a class from the list works to the middle');
|
||||
t.end();
|
||||
});
|
38
dashboard-ui/bower_components/dragula.js/test/containers.js
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('drake defaults to no containers', function (t) {
|
||||
var drake = dragula();
|
||||
t.ok(Array.isArray(drake.containers), 'drake.containers is an array');
|
||||
t.equal(drake.containers.length, 0, 'drake.containers is empty');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('drake reads containers from array argument', function (t) {
|
||||
var el = document.createElement('div');
|
||||
var containers = [el];
|
||||
var drake = dragula(containers);
|
||||
t.equal(drake.containers, containers, 'drake.containers matches input');
|
||||
t.equal(drake.containers.length, 1, 'drake.containers has one item');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('drake reads containers from array in options', function (t) {
|
||||
var el = document.createElement('div');
|
||||
var containers = [el];
|
||||
var drake = dragula({ containers: containers });
|
||||
t.equal(drake.containers, containers, 'drake.containers matches input');
|
||||
t.equal(drake.containers.length, 1, 'drake.containers has one item');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('containers in options take precedent', function (t) {
|
||||
var el = document.createElement('div');
|
||||
var containers = [el];
|
||||
var drake = dragula([], { containers: containers });
|
||||
t.equal(drake.containers, containers, 'drake.containers matches input');
|
||||
t.equal(drake.containers.length, 1, 'drake.containers has one item');
|
||||
t.end();
|
||||
});
|
19
dashboard-ui/bower_components/dragula.js/test/defaults.js
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('drake has sensible default options', function (t) {
|
||||
var options = {};
|
||||
dragula(options);
|
||||
t.equal(typeof options.moves, 'function', 'options.moves defaults to a method');
|
||||
t.equal(typeof options.accepts, 'function', 'options.accepts defaults to a method');
|
||||
t.equal(typeof options.invalid, 'function', 'options.invalid defaults to a method');
|
||||
t.equal(typeof options.isContainer, 'function', 'options.isContainer defaults to a method');
|
||||
t.equal(options.copy, false, 'options.copy defaults to false');
|
||||
t.equal(options.revertOnSpill, false, 'options.revertOnSpill defaults to false');
|
||||
t.equal(options.removeOnSpill, false, 'options.removeOnSpill defaults to false');
|
||||
t.equal(options.direction, 'vertical', 'options.direction defaults to \'vertical\'');
|
||||
t.equal(options.mirrorContainer, document.body, 'options.mirrorContainer defaults to an document.body');
|
||||
t.end();
|
||||
});
|
103
dashboard-ui/bower_components/dragula.js/test/destroy.js
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('destroy does not throw when not dragging, destroyed, or whatever', function (t) {
|
||||
t.test('a single time', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.destroy();
|
||||
}, 'dragula bites into a single call to drake.destroy');
|
||||
st.end();
|
||||
});
|
||||
t.test('multiple times', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.destroy();
|
||||
drake.destroy();
|
||||
drake.destroy();
|
||||
drake.destroy();
|
||||
}, 'dragula bites into multiple calls to drake.destroy');
|
||||
st.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and destroy gets called, nothing happens', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.destroy();
|
||||
t.equal(div.children.length, 1, 'nothing happens');
|
||||
t.equal(drake.dragging, false, 'drake has stopped dragging');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and destroy gets called, dragend event is emitted gracefully', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.on('dragend', dragend);
|
||||
drake.destroy();
|
||||
t.plan(1);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and destroy gets called, default does not revert', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item);
|
||||
div2.appendChild(item);
|
||||
drake.on('drop', drop);
|
||||
drake.on('dragend', dragend);
|
||||
drake.destroy();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function drop (target, parent, source) {
|
||||
t.equal(target, item, 'drop was invoked with item');
|
||||
t.equal(parent, div2, 'drop was invoked with final container');
|
||||
t.equal(source, div, 'drop was invoked with source container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and destroy gets called, revert is executed', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div, div2], { revertOnSpill: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item);
|
||||
div2.appendChild(item);
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('dragend', dragend);
|
||||
drake.destroy();
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function cancel (target, container) {
|
||||
t.equal(target, item, 'cancel was invoked with item');
|
||||
t.equal(container, div, 'cancel was invoked with container');
|
||||
}
|
||||
});
|
256
dashboard-ui/bower_components/dragula.js/test/drag.js
vendored
Normal file
|
@ -0,0 +1,256 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var events = require('./lib/events');
|
||||
var dragula = require('..');
|
||||
|
||||
test('drag event gets emitted when clicking an item', function (t) {
|
||||
testCase('works for left clicks', { which: 0 });
|
||||
testCase('works for wheel clicks', { which: 1 });
|
||||
testCase('works when clicking buttons by default', { which: 0 }, { tag: 'button', passes: true });
|
||||
testCase('works when clicking anchors by default', { which: 0 }, { tag: 'a', passes: true });
|
||||
testCase('fails for right clicks', { which: 2 }, { passes: false });
|
||||
testCase('fails for meta-clicks', { which: 0, metaKey: true }, { passes: false });
|
||||
testCase('fails for ctrl-clicks', { which: 0, ctrlKey: true }, { passes: false });
|
||||
testCase('fails when clicking containers', { which: 0 }, { containerClick: true, passes: false });
|
||||
testCase('fails whenever invalid returns true', { which: 0 }, { passes: false, dragulaOpts: { invalid: always } });
|
||||
testCase('fails whenever moves returns false', { which: 0 }, { passes: false, dragulaOpts: { moves: never } });
|
||||
t.end();
|
||||
function testCase (desc, eventOptions, options) {
|
||||
t.test(desc, function subtest (st) {
|
||||
var o = options || {};
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement(o.tag || 'div');
|
||||
var passes = o.passes !== false;
|
||||
var drake = dragula([div], o.dragulaOpts);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('drag', drag);
|
||||
events.raise(o.containerClick ? div : item, 'mousedown', eventOptions);
|
||||
events.raise(o.containerClick ? div : item, 'mousemove');
|
||||
st.plan(passes ? 4 : 1);
|
||||
st.equal(drake.dragging, passes, desc + ': final state is drake is ' + (passes ? '' : 'not ') + 'dragging');
|
||||
st.end();
|
||||
function drag (target, container) {
|
||||
st[passes ? 'pass' : 'fail'](desc + ': drag event was emitted synchronously');
|
||||
st.equal(target, item, desc + ': first argument is selected item');
|
||||
st.equal(container, div, desc + ': second argument is container');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('when already dragging, mousedown/mousemove ends (cancels) previous drag', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item1 = document.createElement('div');
|
||||
var item2 = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item1);
|
||||
div.appendChild(item2);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item1);
|
||||
drake.on('dragend', end);
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('drag', drag);
|
||||
events.raise(item2, 'mousedown', { which: 0 });
|
||||
events.raise(item2, 'mousemove', { which: 0 });
|
||||
t.plan(7);
|
||||
t.equal(drake.dragging, true, 'final state is drake is dragging');
|
||||
t.end();
|
||||
function end (item) {
|
||||
t.equal(item, item1, 'dragend invoked with correct item');
|
||||
}
|
||||
function cancel (item, source) {
|
||||
t.equal(item, item1, 'cancel invoked with correct item');
|
||||
t.equal(source, div, 'cancel invoked with correct source');
|
||||
}
|
||||
function drag (item, container) {
|
||||
t.pass('drag event was emitted synchronously');
|
||||
t.equal(item, item2, 'first argument is selected item');
|
||||
t.equal(container, div, 'second argument is container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when already dragged, ends (drops) previous drag', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item1 = document.createElement('div');
|
||||
var item2 = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item1);
|
||||
div.appendChild(item2);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item1);
|
||||
div2.appendChild(item1);
|
||||
drake.on('dragend', end);
|
||||
drake.on('drop', drop);
|
||||
drake.on('drag', drag);
|
||||
events.raise(item2, 'mousedown', { which: 0 });
|
||||
events.raise(item2, 'mousemove', { which: 0 });
|
||||
t.plan(8);
|
||||
t.equal(drake.dragging, true, 'final state is drake is dragging');
|
||||
t.end();
|
||||
function end (item) {
|
||||
t.equal(item, item1, 'dragend invoked with correct item');
|
||||
}
|
||||
function drop (item, target, source) {
|
||||
t.equal(item, item1, 'drop invoked with correct item');
|
||||
t.equal(source, div, 'drop invoked with correct source');
|
||||
t.equal(target, div2, 'drop invoked with correct target');
|
||||
}
|
||||
function drag (item, container) {
|
||||
t.pass('drag event was emitted synchronously');
|
||||
t.equal(item, item2, 'first argument is selected item');
|
||||
t.equal(container, div, 'second argument is container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when copying, emits cloned with the copy', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item1 = document.createElement('div');
|
||||
var item2 = document.createElement('span');
|
||||
var drake = dragula([div], { copy: true });
|
||||
item2.innerHTML = '<em>the force is <strong>with this one</strong></em>';
|
||||
div.appendChild(item1);
|
||||
div.appendChild(item2);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item1);
|
||||
drake.on('cloned', cloned);
|
||||
drake.on('drag', drag);
|
||||
events.raise(item2, 'mousedown', { which: 0 });
|
||||
events.raise(item2, 'mousemove', { which: 0 });
|
||||
t.plan(12);
|
||||
t.equal(drake.dragging, true, 'final state is drake is dragging');
|
||||
t.end();
|
||||
function cloned (copy, item) {
|
||||
t.notEqual(copy, item2, 'first argument is not exactly the target');
|
||||
t.equal(copy.tagName, item2.tagName, 'first argument has same tag as target');
|
||||
t.equal(copy.innerHTML, item2.innerHTML, 'first argument has same inner html as target');
|
||||
t.equal(item, item2, 'second argument is clicked item');
|
||||
}
|
||||
function drag (item, container) {
|
||||
t.pass('drag event was emitted synchronously');
|
||||
t.equal(item, item2, 'first argument is selected item');
|
||||
t.equal(container, div, 'second argument is container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging, element gets gu-transit class', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.equal(item.className, 'gu-transit', 'item has gu-transit class');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging, body gets gu-unselectable class', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.equal(document.body.className, 'gu-unselectable', 'body has gu-unselectable class');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging, element gets a mirror image for show', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
item.innerHTML = '<em>the force is <strong>with this one</strong></em>';
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('cloned', cloned);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function cloned (mirror, target) {
|
||||
t.equal(item.className, 'gu-transit', 'item does not have gu-mirror class');
|
||||
t.equal(mirror.className, 'gu-mirror', 'mirror only has gu-mirror class');
|
||||
t.equal(mirror.innerHTML, item.innerHTML, 'mirror is passed to \'cloned\' event');
|
||||
t.equal(target, item, 'cloned lets you know that the mirror is a clone of `item`');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging, mirror element gets appended to configured mirrorContainer', function (t) {
|
||||
var mirrorContainer = document.createElement('div');
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], {
|
||||
'mirrorContainer': mirrorContainer
|
||||
});
|
||||
item.innerHTML = '<em>the force is <strong>with this one</strong></em>';
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('cloned', cloned);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.plan(1);
|
||||
t.end();
|
||||
function cloned (mirror) {
|
||||
t.equal(mirror.parentNode, mirrorContainer, 'mirrors parent is the configured mirrorContainer');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging stops, element gets gu-transit class removed', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.equal(item.className, 'gu-transit', 'item has gu-transit class');
|
||||
drake.end();
|
||||
t.equal(item.className, '', 'item has gu-transit class removed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging stops, body becomes selectable again', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.equal(document.body.className, 'gu-unselectable', 'body has gu-unselectable class');
|
||||
drake.end();
|
||||
t.equal(document.body.className, '', 'body got gu-unselectable class removed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when drag begins, check for copy option', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
item.className = 'copyable';
|
||||
div.className = 'contains';
|
||||
var drake = dragula([div], {
|
||||
copy: checkCondition
|
||||
});
|
||||
item.innerHTML = '<em>the force is <strong>with this one</strong></em>';
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 }); // ensure the copy method condition is only asserted once
|
||||
t.plan(2);
|
||||
t.end();
|
||||
function checkCondition (el, source) {
|
||||
t.equal(el.className, 'copyable', 'dragged element classname is copyable');
|
||||
t.equal(source.className, 'contains', 'source container classname is contains');
|
||||
return true;
|
||||
}
|
||||
drake.end();
|
||||
});
|
||||
|
||||
function always () { return true; }
|
||||
function never () { return false; }
|
27
dashboard-ui/bower_components/dragula.js/test/drake-api.js
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('drake can be instantiated without throwing', function (t) {
|
||||
t.doesNotThrow(drakeFactory, 'calling dragula() without arguments does not throw');
|
||||
t.end();
|
||||
function drakeFactory () {
|
||||
return dragula();
|
||||
}
|
||||
});
|
||||
|
||||
test('drake has expected api properties', function (t) {
|
||||
var drake = dragula();
|
||||
t.ok(drake, 'drake is not null');
|
||||
t.equal(typeof drake, 'object', 'drake is an object');
|
||||
t.ok(Array.isArray(drake.containers), 'drake.containers is an array');
|
||||
t.equal(typeof drake.start, 'function', 'drake.start is a method');
|
||||
t.equal(typeof drake.end, 'function', 'drake.end is a method');
|
||||
t.equal(typeof drake.cancel, 'function', 'drake.cancel is a method');
|
||||
t.equal(typeof drake.remove, 'function', 'drake.remove is a method');
|
||||
t.equal(typeof drake.destroy, 'function', 'drake.destroy is a method');
|
||||
t.equal(typeof drake.dragging, 'boolean', 'drake.dragging is a boolean');
|
||||
t.equal(drake.dragging, false, 'drake.dragging is initialized as false');
|
||||
t.end();
|
||||
});
|
77
dashboard-ui/bower_components/dragula.js/test/end.js
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('end does not throw when not dragging', function (t) {
|
||||
t.test('a single time', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.end();
|
||||
}, 'dragula ignores a single call to drake.end');
|
||||
st.end();
|
||||
});
|
||||
t.test('multiple times', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.end();
|
||||
drake.end();
|
||||
drake.end();
|
||||
drake.end();
|
||||
}, 'dragula ignores multiple calls to drake.end');
|
||||
st.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when already dragging, .end() ends (cancels) previous drag', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item1 = document.createElement('div');
|
||||
var item2 = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item1);
|
||||
div.appendChild(item2);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item1);
|
||||
drake.on('dragend', end);
|
||||
drake.on('cancel', cancel);
|
||||
drake.end();
|
||||
t.plan(4);
|
||||
t.equal(drake.dragging, false, 'final state is: drake is not dragging');
|
||||
t.end();
|
||||
function end (item) {
|
||||
t.equal(item, item1, 'dragend invoked with correct item');
|
||||
}
|
||||
function cancel (item, source) {
|
||||
t.equal(item, item1, 'cancel invoked with correct item');
|
||||
t.equal(source, div, 'cancel invoked with correct source');
|
||||
}
|
||||
});
|
||||
|
||||
test('when already dragged, ends (drops) previous drag', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item1 = document.createElement('div');
|
||||
var item2 = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item1);
|
||||
div.appendChild(item2);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.start(item1);
|
||||
div2.appendChild(item1);
|
||||
drake.on('dragend', end);
|
||||
drake.on('drop', drop);
|
||||
drake.end();
|
||||
t.plan(5);
|
||||
t.equal(drake.dragging, false, 'final state is: drake is not dragging');
|
||||
t.end();
|
||||
function end (item) {
|
||||
t.equal(item, item1, 'dragend invoked with correct item');
|
||||
}
|
||||
function drop (item, target, source) {
|
||||
t.equal(item, item1, 'drop invoked with correct item');
|
||||
t.equal(source, div, 'drop invoked with correct source');
|
||||
t.equal(target, div2, 'drop invoked with correct target');
|
||||
}
|
||||
});
|
292
dashboard-ui/bower_components/dragula.js/test/events.js
vendored
Normal file
|
@ -0,0 +1,292 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var events = require('./lib/events');
|
||||
var dragula = require('..');
|
||||
|
||||
test('.start() emits "cloned" for copies', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { copy: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('cloned', cloned);
|
||||
drake.start(item);
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function cloned (copy, original, type) {
|
||||
if (type === 'copy') {
|
||||
t.notEqual(copy, item, 'copy is not a reference to item');
|
||||
t.deepEqual(copy, item, 'copy of original is provided');
|
||||
t.equal(original, item, 'original item is provided');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('.start() emits "drag" for items', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('drag', drag);
|
||||
drake.start(item);
|
||||
t.plan(2);
|
||||
t.end();
|
||||
function drag (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.end() emits "cancel" when not moved', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('cancel', cancel);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.end();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function cancel (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.end() emits "drop" when moved', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div, div2]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('drop', drop);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
div2.appendChild(item);
|
||||
drake.end();
|
||||
t.plan(5);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function drop (original, target, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(target, div2, 'target matches expected div');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.remove() emits "remove" for items', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('remove', remove);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.remove();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function remove (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.remove() emits "cancel" for copies', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { copy: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('cancel', cancel);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.remove();
|
||||
t.plan(6);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got invoked');
|
||||
}
|
||||
function out (copy) {
|
||||
t.notEqual(copy, item, 'copy is not a reference to item');
|
||||
t.deepEqual(copy, item, 'item is a copy of item');
|
||||
}
|
||||
function cancel (copy, container) {
|
||||
t.notEqual(copy, item, 'copy is not a reference to item');
|
||||
t.deepEqual(copy, item, 'item is a copy of item');
|
||||
t.equal(container, null, 'container matches expectation');
|
||||
}
|
||||
});
|
||||
|
||||
test('.cancel() emits "cancel" when not moved', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('cancel', cancel);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.cancel();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function cancel (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.cancel() emits "drop" when not reverted', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('drop', drop);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
div2.appendChild(item);
|
||||
drake.cancel();
|
||||
t.plan(5);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function drop (original, parent, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(parent, div2, 'parent matches expected div');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('.cancel() emits "cancel" when reverts', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var div2 = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { revertOnSpill: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
document.body.appendChild(div2);
|
||||
drake.on('dragend', dragend);
|
||||
drake.on('out', out);
|
||||
drake.on('cancel', cancel);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
div2.appendChild(item);
|
||||
drake.cancel();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function out (original) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
}
|
||||
function cancel (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
||||
|
||||
test('mousedown emits "cloned" for mirrors', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('cloned', cloned);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function cloned (copy, original, type) {
|
||||
if (type === 'mirror') {
|
||||
t.notEqual(copy, item, 'mirror is not a reference to item');
|
||||
t.deepEqual(copy, item, 'mirror of original is provided');
|
||||
t.equal(original, item, 'original item is provided');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('mousedown emits "cloned" for copies', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { copy: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('cloned', cloned);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function cloned (copy, original, type) {
|
||||
if (type === 'copy') {
|
||||
t.notEqual(copy, item, 'copy is not a reference to item');
|
||||
t.deepEqual(copy, item, 'copy of original is provided');
|
||||
t.equal(original, item, 'original item is provided');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('mousedown emits "drag" for items', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.on('drag', drag);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
t.plan(2);
|
||||
t.end();
|
||||
function drag (original, container) {
|
||||
t.equal(original, item, 'item is a reference to moving target');
|
||||
t.equal(container, div, 'container matches expected div');
|
||||
}
|
||||
});
|
16
dashboard-ui/bower_components/dragula.js/test/lib/events.js
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
'use strict';
|
||||
|
||||
function raise (el, type, options) {
|
||||
var o = options || {};
|
||||
var e = document.createEvent('Event');
|
||||
e.initEvent(type, true, true);
|
||||
Object.keys(o).forEach(apply);
|
||||
el.dispatchEvent(e);
|
||||
function apply (key) {
|
||||
e[key] = o[key];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
raise: raise
|
||||
};
|
9
dashboard-ui/bower_components/dragula.js/test/public-api.js
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var dragula = require('..');
|
||||
|
||||
test('public api matches expectation', function (t) {
|
||||
t.equal(typeof dragula, 'function', 'dragula is a function');
|
||||
t.end();
|
||||
});
|
106
dashboard-ui/bower_components/dragula.js/test/remove.js
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var events = require('./lib/events');
|
||||
var dragula = require('..');
|
||||
|
||||
test('remove does not throw when not dragging', function (t) {
|
||||
t.test('a single time', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.remove();
|
||||
}, 'dragula ignores a single call to drake.remove');
|
||||
st.end();
|
||||
});
|
||||
t.test('multiple times', function once (st) {
|
||||
var drake = dragula();
|
||||
st.doesNotThrow(function () {
|
||||
drake.remove();
|
||||
drake.remove();
|
||||
drake.remove();
|
||||
drake.remove();
|
||||
}, 'dragula ignores multiple calls to drake.remove');
|
||||
st.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and remove gets called, element is removed', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.remove();
|
||||
t.equal(div.children.length, 0, 'item got removed from container');
|
||||
t.equal(drake.dragging, false, 'drake has stopped dragging');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('when dragging and remove gets called, remove event is emitted', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div]);
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
drake.start(item);
|
||||
drake.on('remove', remove);
|
||||
drake.on('dragend', dragend);
|
||||
drake.remove();
|
||||
t.plan(3);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function remove (target, container) {
|
||||
t.equal(target, item, 'remove was invoked with item');
|
||||
t.equal(container, div, 'remove was invoked with container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and remove gets called, cancel event is emitted', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { copy: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('dragend', dragend);
|
||||
drake.remove();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function cancel (target, container) {
|
||||
t.equal(target.className, 'gu-transit', 'cancel was invoked with item');
|
||||
t.notEqual(target, item, 'item is a copy and not the original');
|
||||
t.equal(container, null, 'cancel was invoked with container');
|
||||
}
|
||||
});
|
||||
|
||||
test('when dragging a copy and remove gets called, cancel event is emitted', function (t) {
|
||||
var div = document.createElement('div');
|
||||
var item = document.createElement('div');
|
||||
var drake = dragula([div], { copy: true });
|
||||
div.appendChild(item);
|
||||
document.body.appendChild(div);
|
||||
events.raise(item, 'mousedown', { which: 0 });
|
||||
events.raise(item, 'mousemove', { which: 0 });
|
||||
drake.on('cancel', cancel);
|
||||
drake.on('dragend', dragend);
|
||||
drake.remove();
|
||||
t.plan(4);
|
||||
t.end();
|
||||
function dragend () {
|
||||
t.pass('dragend got called');
|
||||
}
|
||||
function cancel (target, container) {
|
||||
t.equal(target.className, 'gu-transit', 'cancel was invoked with item');
|
||||
t.notEqual(target, item, 'item is a copy and not the original');
|
||||
t.equal(container, null, 'cancel was invoked with container');
|
||||
}
|
||||
});
|
|
@ -76,6 +76,23 @@
|
|||
var elem = page.querySelector('#childrenContent .itemsContainer');
|
||||
elem.innerHTML = html;
|
||||
|
||||
var listItems = [];
|
||||
var elems = elem.querySelectorAll('PAPER-ICON-ITEM');
|
||||
for (var i = 0, length = elems.length; i < length; i++) {
|
||||
listItems.push(elems[i]);
|
||||
}
|
||||
|
||||
Dashboard.loadDragula(function (dragula) {
|
||||
|
||||
dragula([elem.querySelector('.paperList')], {
|
||||
direction: 'vertical',
|
||||
revertOnSpill: true
|
||||
}).on('drop', function (el, target, source, sibling) {
|
||||
onDrop(el, target, source, sibling, page, item);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
ImageLoader.lazyChildren(elem);
|
||||
|
||||
$(elem).off('needsrefresh').on('needsrefresh', function () {
|
||||
|
@ -85,10 +102,8 @@
|
|||
}).off('removefromplaylist').on('removefromplaylist', function (e, playlistItemId) {
|
||||
|
||||
removeFromPlaylist(page, item, [playlistItemId]);
|
||||
|
||||
});
|
||||
|
||||
|
||||
$('.btnNextPage', elem).on('click', function () {
|
||||
query.StartIndex += query.Limit;
|
||||
reloadItems(page, item);
|
||||
|
@ -103,6 +118,42 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onDrop(el, target, source, sibling, page, item) {
|
||||
|
||||
var parent = $(el).parents('.paperList')[0];
|
||||
var newIndex;
|
||||
|
||||
if (sibling) {
|
||||
|
||||
newIndex = parseInt(sibling.getAttribute('data-index'));
|
||||
|
||||
} else {
|
||||
|
||||
// dropped at the end
|
||||
newIndex = parent.querySelectorAll('paper-icon-item').length;
|
||||
}
|
||||
|
||||
var itemId = el.getAttribute('data-playlistitemid');
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
ApiClient.ajax({
|
||||
|
||||
url: ApiClient.getUrl('Playlists/' + item.Id + '/Items/' + itemId + '/Move/' + newIndex),
|
||||
|
||||
type: 'POST'
|
||||
|
||||
}).done(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
}).fail(function () {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
reloadItems(page, item);
|
||||
});
|
||||
}
|
||||
|
||||
function removeFromPlaylist(page, item, ids) {
|
||||
|
||||
ApiClient.ajax({
|
||||
|
|
|
@ -1706,6 +1706,17 @@ var Dashboard = {
|
|||
|
||||
exit: function () {
|
||||
Dashboard.logout();
|
||||
},
|
||||
|
||||
loadDragula: function (callback) {
|
||||
|
||||
require(['dragula'], function (dragula) {
|
||||
|
||||
Dashboard.importCss('bower_components/dragula.js/dist/dragula.min.css');
|
||||
|
||||
callback(dragula);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2051,7 +2062,8 @@ var AppInfo = {};
|
|||
directorybrowser: 'components/directorybrowser/directorybrowser',
|
||||
collectioneditor: 'components/collectioneditor/collectioneditor',
|
||||
playlisteditor: 'components/playlisteditor/playlisteditor',
|
||||
howler: 'bower_components/howler.js/howler.min'
|
||||
howler: 'bower_components/howler.js/howler.min',
|
||||
dragula: 'bower_components/dragula.js/dist/dragula.min'
|
||||
};
|
||||
|
||||
if (Dashboard.isRunningInCordova()) {
|
||||
|
|