From c2b461362710dd4101ddd4dc5711a47939a93a9d Mon Sep 17 00:00:00 2001 From: RubaXa Date: Sat, 20 Dec 2014 14:46:12 +0300 Subject: [PATCH 01/41] #186: remove 'meteor' folder --- meteor/README.md | 106 --------- meteor/example/.meteor/.gitignore | 1 - meteor/example/.meteor/packages | 12 -- meteor/example/.meteor/release | 1 - meteor/example/.meteor/versions | 56 ----- meteor/example/README.md | 60 ------ meteor/example/client/define-object-type.css | 57 ----- meteor/example/client/define-object-type.html | 94 -------- meteor/example/client/define-object-type.js | 101 --------- meteor/example/model.js | 2 - meteor/example/package.json | 1 - meteor/example/packages/Sortable | 1 - meteor/example/run.bat | 4 - meteor/example/run.sh | 15 -- meteor/example/server/fixtures.js | 75 ------- meteor/methods.js | 20 -- meteor/package.js | 34 --- meteor/publish.sh | 40 ---- meteor/reactivize.js | 201 ------------------ meteor/runtests.sh | 46 ---- meteor/template.html | 5 - meteor/test.js | 9 - 22 files changed, 941 deletions(-) delete mode 100644 meteor/README.md delete mode 100644 meteor/example/.meteor/.gitignore delete mode 100644 meteor/example/.meteor/packages delete mode 100644 meteor/example/.meteor/release delete mode 100644 meteor/example/.meteor/versions delete mode 100644 meteor/example/README.md delete mode 100644 meteor/example/client/define-object-type.css delete mode 100644 meteor/example/client/define-object-type.html delete mode 100644 meteor/example/client/define-object-type.js delete mode 100644 meteor/example/model.js delete mode 120000 meteor/example/package.json delete mode 120000 meteor/example/packages/Sortable delete mode 100755 meteor/example/run.bat delete mode 100755 meteor/example/run.sh delete mode 100644 meteor/example/server/fixtures.js delete mode 100644 meteor/methods.js delete mode 100644 meteor/package.js delete mode 100755 meteor/publish.sh delete mode 100644 meteor/reactivize.js delete mode 100755 meteor/runtests.sh delete mode 100644 meteor/template.html delete mode 100644 meteor/test.js diff --git a/meteor/README.md b/meteor/README.md deleted file mode 100644 index 163223bbe..000000000 --- a/meteor/README.md +++ /dev/null @@ -1,106 +0,0 @@ -Reactive reorderable lists with [Sortable](http://rubaxa.github.io/Sortable/), -backed by [Meteor.js](http://meteor.com) collections: - -* new elements arriving in the collection will update the list as you expect -* elements removed from the collection will be removed from the list -* drag and drop between lists updates collections accordingly - -Demo: http://rubaxa-sortable.meteor.com - -# Meteor - -If you're new to Meteor, here's what the excitement is all about - -[watch the first two minutes](https://www.youtube.com/watch?v=fsi0aJ9yr2o); you'll be hooked by 1:28. -That screencast is from 2012. In the meantime, Meteor has become a mature JavaScript-everywhere web -development framework. Read more at [Why Meteor](http://www.meteorpedia.com/read/Why_Meteor). - - -# Usage - -Simplest invocation - order will be lost when the page is refreshed: - -```handlebars -{{sortable }} -``` - -Persist the sort order in the 'order' field of each document in the collection: - -```handlebars -{{sortable items= sortField="order"}} -``` - -Along with `items`, `sortField` is the only Meteor-specific option. If it's missing, the package will -assume there is a field called "order" in the collection, holding unique `Number`s such that every -`order` differs from that before and after it by at least 1. Basically, keep to 0, 1, 2, ... . -Try not to depend on a particular format for this field; it *is* though guaranteed that a `sort` will -produce lexicographical order, and that the order will be maintained after an arbitrary number of -reorderings, unlike with [naive solutions](http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible). - - -## Passing options to the Sortable library - - {{sortable items= option1=value1 option2=value2...}} - {{sortable items= options=myOptions}} - -For available options, please refer to [the main README](../README.md#options). You can pass them directly -or under the `options` object. Direct options (`key=value`) override those in `options`. It is best -to pass presentation-related options directly, and functionality-related settings in an `options` -object, as this will enable designers to work without needing to inspect the JavaScript code: - - - -Define the options in a helper for the template that calls Sortable: - -```js -Template.myTemplate.helpers({ - playerOptions: function () { - return { - group: { - name: "league", - pull: true, - put: false - }, - sort: false - }; - } -}); -``` - - -## Events - -All the original Sortable events are supported. In addition, they will receive -the data context in `event.data`. You can access `event.data.order` this way: - -```handlebars -{{sortable items=players options=playersOptions}} -``` - -```js -Template.myTemplate.helpers({ - playersOptions: function () { - return { - onSort: function(/**Event*/event) { - console.log('Moved player #%d from %d to %d', - event.data.order, event.oldIndex, event.newIndex - ); - } - }; - } -}); -``` - - -# Issues - -If you encounter an issue while using this package, please CC @dandv when you file it in this repo. - - -# TODO - -* Array support -* Tests -* Misc. - see reactivize.js diff --git a/meteor/example/.meteor/.gitignore b/meteor/example/.meteor/.gitignore deleted file mode 100644 index 408303742..000000000 --- a/meteor/example/.meteor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -local diff --git a/meteor/example/.meteor/packages b/meteor/example/.meteor/packages deleted file mode 100644 index a33b0edfd..000000000 --- a/meteor/example/.meteor/packages +++ /dev/null @@ -1,12 +0,0 @@ -# Meteor packages used by this project, one per line. -# -# 'meteor add' and 'meteor remove' will edit this file for you, -# but you can also edit it by hand. - -meteor-platform -autopublish -insecure -rubaxa:sortable -dburles:mongo-collection-instances -fezvrasta:bootstrap-material-design -# twbs:bootstrap diff --git a/meteor/example/.meteor/release b/meteor/example/.meteor/release deleted file mode 100644 index f1b625596..000000000 --- a/meteor/example/.meteor/release +++ /dev/null @@ -1 +0,0 @@ -METEOR@1.0.1 diff --git a/meteor/example/.meteor/versions b/meteor/example/.meteor/versions deleted file mode 100644 index ce300af69..000000000 --- a/meteor/example/.meteor/versions +++ /dev/null @@ -1,56 +0,0 @@ -application-configuration@1.0.3 -autopublish@1.0.1 -autoupdate@1.1.3 -base64@1.0.1 -binary-heap@1.0.1 -blaze-tools@1.0.1 -blaze@2.0.3 -boilerplate-generator@1.0.1 -callback-hook@1.0.1 -check@1.0.2 -ctl-helper@1.0.4 -ctl@1.0.2 -dburles:mongo-collection-instances@0.2.5 -ddp@1.0.12 -deps@1.0.5 -ejson@1.0.4 -fastclick@1.0.1 -fezvrasta:bootstrap-material-design@0.2.1 -follower-livedata@1.0.2 -geojson-utils@1.0.1 -html-tools@1.0.2 -htmljs@1.0.2 -http@1.0.8 -id-map@1.0.1 -insecure@1.0.1 -jquery@1.0.1 -json@1.0.1 -launch-screen@1.0.0 -livedata@1.0.11 -logging@1.0.5 -meteor-platform@1.2.0 -meteor@1.1.3 -minifiers@1.1.2 -minimongo@1.0.5 -mobile-status-bar@1.0.1 -mongo@1.0.9 -observe-sequence@1.0.3 -ordered-dict@1.0.1 -random@1.0.1 -reactive-dict@1.0.4 -reactive-var@1.0.3 -reload@1.1.1 -retry@1.0.1 -routepolicy@1.0.2 -rubaxa:sortable@1.0.0 -session@1.0.4 -spacebars-compiler@1.0.3 -spacebars@1.0.3 -templating@1.0.9 -tracker@1.0.3 -twbs:bootstrap@3.3.1 -ui@1.0.4 -underscore@1.0.1 -url@1.0.2 -webapp-hashing@1.0.1 -webapp@1.1.4 diff --git a/meteor/example/README.md b/meteor/example/README.md deleted file mode 100644 index e18ca52ce..000000000 --- a/meteor/example/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# RubaXa:Sortable Meteor demo - -This demo showcases the two-way integration between the reorderable list -widget [Sortable](https://github.com/RubaXa/Sortable/) and Meteor.js. Meteor -Mongo collections are updated when items are added, removed or reordered, and -the order is persisted. - -It also shows list grouping and control over what lists can give or receive -elements. You can only drag elements from the list to the left onto the list -to the right. - -## Usage - -The example uses the local package from the checkout, so it needs to wire -up some files (`package.js` and `package.json`). This is done by the handy -run script: - -### Windows - - git clone git@github.com:RubaXa/Sortable.git - cd Sortable - git checkout dev - cd meteor\example - run.bat - -### Elsewhere - - git clone git@github.com:RubaXa/Sortable.git - cd Sortable - git checkout dev - meteor/example./run.sh - -## Prior art - -### Differential - -Differential wrote [a blog post on reorderable lists with -Meteor](differential.com/blog/sortable-lists-in-meteor-using-jquery-ui) and -[jQuery UI Sortable](http://jqueryui.com/sortable/). It served as inspiration -for integrating [rubaxa:sortable](rubaxa.github.io/Sortable/), -which uses the HTML5 native drag&drop API (not without [its -limitations](https://github.com/RubaXa/Sortable/issues/106)). -The reordering method used by the Differential example can lead to data loss -though, because it calculates the new order of a dropped element as the -arithmetic mean of the elements before and after it. This [runs into limitations -of floating point precision](http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible) -in JavaScript after <50 reorderings. - -### Todos animated - -http://todos-dnd-animated.meteor.com/ ([source](https://github.com/nleush/meteor-todos-sortable-animation)) -is based on old Meteor Blaze (back then Spark) API, and won't work with current versions. -It does showcase some neat features, such as animation when collection elements -are reordered by another client. It uses jQuery UI Sortable as well, which lacks -some features vs. rubaxa:Sortable, e.g. text selection within the item. - -## TODO - -* Animation -* Indication that an item is being edited diff --git a/meteor/example/client/define-object-type.css b/meteor/example/client/define-object-type.css deleted file mode 100644 index d67b4b1d7..000000000 --- a/meteor/example/client/define-object-type.css +++ /dev/null @@ -1,57 +0,0 @@ -.glyphicon { - vertical-align: baseline; - font-size: 80%; - margin-right: 0.5em; -} - -[class^="mdi-"], [class*=" mdi-"] { - vertical-align: baseline; - font-size: 90%; - margin-right: 0.4em; -} - -.list-pair { - display: flex; /* use the flexbox model */ - flex-direction: row; -} -.sortable { -/* font-size: 2em;*/ -} - -.sortable.source { - /*background: #9FA8DA;*/ - flex: 0 0 auto; - margin-right: 1em; - cursor: move; - cursor: -webkit-grabbing; -} - -.sortable.target { - /*background: #3F51B5;*/ - flex: 1 1 auto; - margin-left: 1em; -} - -.target .well { - -} - -.sortable-handle { - cursor: move; - cursor: -webkit-grabbing; -} -.sortable-handle.pull-right { - margin-top: 0.3em; -} - -.sortable-ghost { - opacity: 0.6; -} - -/* show the remove button on hover */ -.removable .close { - display: none; -} -.removable:hover .close { - display: block; -} diff --git a/meteor/example/client/define-object-type.html b/meteor/example/client/define-object-type.html deleted file mode 100644 index d852cbcb5..000000000 --- a/meteor/example/client/define-object-type.html +++ /dev/null @@ -1,94 +0,0 @@ - - Reactive RubaXa:Sortable for Meteor - - - - {{> navbar}} - -
- - - {{> typeDefinition}} -
- - - - - - - - \ No newline at end of file diff --git a/meteor/example/client/define-object-type.js b/meteor/example/client/define-object-type.js deleted file mode 100644 index ad2a19e2a..000000000 --- a/meteor/example/client/define-object-type.js +++ /dev/null @@ -1,101 +0,0 @@ -// Define an object type by dragging together attributes - -Template.typeDefinition.helpers({ - types: function () { - return Types.find({}, { sort: { order: 1 } }); - }, - typesOptions: { - sortField: 'order', // defaults to 'order' anyway - group: { - name: 'typeDefinition', - pull: 'clone', - put: false - }, - sort: false // don't allow reordering the types, just the attributes below - }, - - attributes: function () { - return Attributes.find({}, { - sort: { order: 1 }, - transform: function (doc) { - doc.icon = Types.findOne({name: doc.type}).icon; - return doc; - } - }); - }, - attributesOptions: { - group: { - name: 'typeDefinition', - put: true - }, - onAdd: function (event) { - delete event.data._id; // Generate a new id when inserting in the Attributes collection. Otherwise, if we add the same type twice, we'll get an error that the ids are not unique. - delete event.data.icon; - event.data.type = event.data.name; - event.data.name = 'Rename me (double click)' - }, - // event handler for reordering attributes - onSort: function (event) { - console.log('Item %s went from #%d to #%d', - event.data.name, event.oldIndex, event.newIndex - ); - } - } -}); - -Template.sortableItemTarget.events({ - 'dblclick .name': function (event, template) { - // Make the name editable. We should use an existing component, but it's - // in a sorry state - https://github.com/arillo/meteor-x-editable/issues/1 - var name = template.$('.name'); - var input = template.$('input'); - if (input.length) { // jQuery never returns null - http://stackoverflow.com/questions/920236/how-can-i-detect-if-a-selector-returns-null - input.show(); - } else { - input = $(''); - name.after(input); - } - name.hide(); - input.focus(); - }, - 'blur input[type=text]': function (event, template) { - // commit the change to the name, if any - var input = template.$('input'); - input.hide(); - template.$('.name').show(); - // TODO - what is the collection here? We'll hard-code for now. - // https://github.com/meteor/meteor/issues/3303 - if (this.name !== input.val() && this.name !== '') - Attributes.update(this._id, {$set: {name: input.val()}}); - }, - 'keydown input[type=text]': function (event, template) { - if (event.which === 27) { - // ESC - discard edits and keep existing value - template.$('input').val(this.name); - event.preventDefault(); - event.target.blur(); - } else if (event.which === 13) { - // ENTER - event.preventDefault(); - event.target.blur(); - } - } -}); - -// you can add events to all Sortable template instances -Template.sortable.events({ - 'click .close': function (event, template) { - // `this` is the data context set by the enclosing block helper (#each, here) - template.collection.remove(this._id); - // custom code, working on a specific collection - if (Attributes.find().count() === 0) { - Meteor.setTimeout(function () { - Attributes.insert({ - name: 'Not nice to delete the entire list! Add some attributes instead.', - type: 'String', - order: 0 - }) - }, 1000); - } - } -}); diff --git a/meteor/example/model.js b/meteor/example/model.js deleted file mode 100644 index 8ae88226a..000000000 --- a/meteor/example/model.js +++ /dev/null @@ -1,2 +0,0 @@ -Types = new Mongo.Collection('types'); -Attributes = new Mongo.Collection('attributes'); diff --git a/meteor/example/package.json b/meteor/example/package.json deleted file mode 120000 index 138a42cdf..000000000 --- a/meteor/example/package.json +++ /dev/null @@ -1 +0,0 @@ -../../package.json \ No newline at end of file diff --git a/meteor/example/packages/Sortable b/meteor/example/packages/Sortable deleted file mode 120000 index 1b20c9fb8..000000000 --- a/meteor/example/packages/Sortable +++ /dev/null @@ -1 +0,0 @@ -../../../ \ No newline at end of file diff --git a/meteor/example/run.bat b/meteor/example/run.bat deleted file mode 100755 index a6d845af5..000000000 --- a/meteor/example/run.bat +++ /dev/null @@ -1,4 +0,0 @@ -mklink ..\..\package.js "meteor/package.js" -mklink package.json "../../package.json" -meteor run -del ..\..\package.js package.json diff --git a/meteor/example/run.sh b/meteor/example/run.sh deleted file mode 100755 index aab44abf2..000000000 --- a/meteor/example/run.sh +++ /dev/null @@ -1,15 +0,0 @@ -# sanity check: make sure we're in the root directory of the example -cd "$( dirname "$0" )" - -# delete temp files even if Ctrl+C is pressed -int_trap() { - echo "Cleaning up..." -} -trap int_trap INT - -ln -s "meteor/package.js" ../../package.js 2>/dev/null -ln -s "../../package.json" package.json 2>/dev/null - -meteor run "$@" - -rm ../../package.js package.json diff --git a/meteor/example/server/fixtures.js b/meteor/example/server/fixtures.js deleted file mode 100644 index 617acf948..000000000 --- a/meteor/example/server/fixtures.js +++ /dev/null @@ -1,75 +0,0 @@ -Meteor.startup(function () { - if (Types.find().count() === 0) { - [ - { - name: 'String', - icon: '' - }, - { - name: 'Text, multi-line', - icon: '' - }, - { - name: 'Category', - icon: '' - }, - { - name: 'Number', - icon: '' - }, - { - name: 'Date', - icon: '' - }, - { - name: 'Hyperlink', - icon: '' - }, - { - name: 'Image', - icon: '' - }, - { - name: 'Progress', - icon: '' - }, - { - name: 'Duration', - icon: '' - }, - { - name: 'Map address', - icon: '' - }, - { - name: 'Relationship', - icon: '' - } - ].forEach(function (type, i) { - Types.insert({ - name: type.name, - icon: type.icon, - order: i - }); - } - ); - console.log('Initialized attribute types.'); - } - - if (Attributes.find().count() === 0) { - [ - { name: 'Name', type: 'String' }, - { name: 'Created at', type: 'Date' }, - { name: 'Link', type: 'Hyperlink' }, - { name: 'Owner', type: 'Relationship' } - ].forEach(function (attribute, i) { - Attributes.insert({ - name: attribute.name, - type: attribute.type, - order: i - }); - } - ); - console.log('Created sample object type.'); - } -}); diff --git a/meteor/methods.js b/meteor/methods.js deleted file mode 100644 index fe8d83433..000000000 --- a/meteor/methods.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -Meteor.methods({ - /** - * Update the orderField of documents with given ids in a collection, incrementing it by incDec - * @param {String} collectionName - name of the collection to update - * @param {String[]} ids - array of document ids - * @param {String} orderField - the name of the order field, usually "order" - * @param {Number} incDec - pass 1 or -1 - */ - 'rubaxa:sortable/collection-update': function (collectionName, ids, orderField, incDec) { - check(collectionName, String); - check(ids, [String]); - check(orderField, String); - check(incDec, Number); - var selector = {_id: {$in: ids}}, modifier = {$inc: {}}; - modifier.$inc[orderField] = incDec; - Mongo.Collection.get(collectionName).update(selector, modifier, {multi: true}); - } -}); diff --git a/meteor/package.js b/meteor/package.js deleted file mode 100644 index 823a0ac2a..000000000 --- a/meteor/package.js +++ /dev/null @@ -1,34 +0,0 @@ -// package metadata file for Meteor.js -'use strict'; - -var packageName = 'rubaxa:sortable'; // http://atmospherejs.com/rubaxa/sortable - -var packageJson = JSON.parse(Npm.require("fs").readFileSync('package.json')); - -Package.describe({ - name: packageName, - summary: 'Sortable: reactive minimalist reorderable drag-and-drop lists on modern browsers and touch devices', - version: packageJson.version, - git: 'https://github.com/RubaXa/Sortable.git', - readme: 'https://github.com/RubaXa/Sortable/blob/master/meteor/README.md' -}); - -Package.onUse(function (api) { - api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0']); - api.use('templating', 'client'); - api.use('dburles:mongo-collection-instances@0.2.5'); // to watch collections getting created - api.export('Sortable'); - api.addFiles([ - 'Sortable.js', - 'meteor/template.html', // the HTML comes first, so reactivize.js can refer to the template in it - 'meteor/reactivize.js' - ], 'client'); - api.addFiles('meteor/methods.js'); // add to both client and server -}); - -Package.onTest(function (api) { - api.use(packageName, 'client'); - api.use('tinytest', 'client'); - - api.addFiles('meteor/test.js', 'client'); -}); diff --git a/meteor/publish.sh b/meteor/publish.sh deleted file mode 100755 index 56cd665ef..000000000 --- a/meteor/publish.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# Publish package to Meteor's repository, Atmospherejs.com - -# Make sure Meteor is installed, per https://www.meteor.com/install. -# The curl'ed script is totally safe; takes 2 minutes to read its source and check. -type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } - -# sanity check: make sure we're in the root directory of the checkout -cd "$( dirname "$0" )/.." - -ALL_EXIT_CODE=0 - -# test any package*.js packages we may have, e.g. package.js, package-compat.js -for PACKAGE_FILE in meteor/package*.js; do - - # Meteor expects package.js to be in the root directory of the checkout, so copy there our package file under that name, temporarily - cp $PACKAGE_FILE ./package.js - - # publish package, creating it if it's the first time we're publishing - PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) - - echo "Publishing $PACKAGE_NAME..." - - # Attempt to re-publish the package - the most common operation once the initial release has - # been made. If the package name was changed (rare), you'll have to pass the --create flag. - meteor publish "$@"; EXIT_CODE=$? - ALL_EXIT_CODE=$(( $ALL_EXIT_CODE + $EXIT_CODE )) - if (( $EXIT_CODE == 0 )); then - echo "Thanks for releasing a new version. You can see it at" - echo "https://atmospherejs.com/${PACKAGE_NAME/://}" - else - echo "We got an error. Please post it at https://github.com/raix/Meteor-community-discussions/issues/14" - fi - - # rm the temporary build files and package.js - rm -rf ".build.$PACKAGE_NAME" versions.json package.js - -done - -exit $ALL_EXIT_CODE diff --git a/meteor/reactivize.js b/meteor/reactivize.js deleted file mode 100644 index 34ff5018d..000000000 --- a/meteor/reactivize.js +++ /dev/null @@ -1,201 +0,0 @@ -/* -Make a Sortable reactive by binding it to a Mongo.Collection. -Calls `rubaxa:sortable/collection-update` on the server to update the sortField or affected records. - -TODO: - * supply consecutive values if the `order` field doesn't have any - * .get(DOMElement) - return the Sortable object of a DOMElement - * create a new _id automatically onAdd if the event.from list had pull: 'clone' - * support arrays - * sparse arrays - * tests - * drop onto existing empty lists - * insert back into lists emptied by dropping - * performance on dragging into long list at the beginning - * handle failures on Collection operations, e.g. add callback to .insert - * when adding elements, update ranks just for the half closer to the start/end of the list - * revisit http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible - * reproduce the insidious bug where the list isn't always sorted (fiddle with dragging #1 over #2, then back, then #N before #1) - - */ - -'use strict'; - -Template.sortable.created = function () { - var templateInstance = this; - // `this` is a template instance that can store properties of our choice - http://docs.meteor.com/#/full/template_inst - if (templateInstance.setupDone) return; // paranoid: only run setup once - // this.data is the data context - http://docs.meteor.com/#/full/template_data - // normalize all options into templateInstance.options, and remove them from .data - templateInstance.options = templateInstance.data.options || {}; - Object.keys(templateInstance.data).forEach(function (key) { - if (key === 'options' || key === 'items') return; - templateInstance.options[key] = templateInstance.data[key]; - delete templateInstance.data[key]; - }); - templateInstance.options.sortField = templateInstance.options.sortField || 'order'; - // We can get the collection via the .collection property of the cursor, but changes made that way - // will NOT be sent to the server - https://github.com/meteor/meteor/issues/3271#issuecomment-66656257 - // Thus we need to use dburles:mongo-collection-instances to get a *real* collection - if (templateInstance.data.items && templateInstance.data.items.collection) { - // cursor passed via items=; its .collection works client-only and has a .name property - templateInstance.collectionName = templateInstance.data.items.collection.name; - templateInstance.collection = Mongo.Collection.get(templateInstance.collectionName); - } else if (templateInstance.data.items) { - // collection passed via items=; does NOT have a .name property, but _name - templateInstance.collection = templateInstance.data.items; - templateInstance.collectionName = templateInstance.collection._name; - } else if (templateInstance.data.collection) { - // cursor passed directly - templateInstance.collectionName = templateInstance.data.collection.name; - templateInstance.collection = Mongo.Collection.get(templateInstance.collectionName); - } else { - templateInstance.collection = templateInstance.data; // collection passed directly - templateInstance.collectionName = templateInstance.collection._name; - } - - // TODO if (Array.isArray(templateInstance.collection)) - - // What if user filters some of the items in the cursor, instead of ordering the entire collection? - // Use case: reorder by preference movies of a given genre, a filter within all movies. - // A: Modify all intervening items **that are on the client**, to preserve the overall order - // TODO: update *all* orders via a server method that takes not ids, but start & end elements - mild security risk - delete templateInstance.data.options; - - /** - * When an element was moved, adjust its orders and possibly the order of - * other elements, so as to maintain a consistent and correct order. - * - * There are three approaches to this: - * 1) Using arbitrary precision arithmetic and setting only the order of the moved - * element to the average of the orders of the elements around it - - * http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible - * The downside is that the order field in the DB will increase by one byte every - * time an element is reordered. - * 2) Adjust the orders of the intervening items. This keeps the orders sane (integers) - * but is slower because we have to modify multiple documents. - * TODO: we may be able to update fewer records by only altering the - * order of the records between the newIndex/oldIndex and the start/end of the list. - * 3) Use regular precision arithmetic, but when the difference between the orders of the - * moved item and the one before/after it falls below a certain threshold, adjust - * the order of that other item, and cascade doing so up or down the list. - * This will keep the `order` field constant in size, and will only occasionally - * require updating the `order` of other records. - * - * For now, we use approach #2. - * - * @param {String} itemId - the _id of the item that was moved - * @param {Number} orderPrevItem - the order of the item before it, or null - * @param {Number} orderNextItem - the order of the item after it, or null - */ - templateInstance.adjustOrders = function adjustOrders(itemId, orderPrevItem, orderNextItem) { - var orderField = templateInstance.options.sortField; - var selector = {}, modifier = {$set: {}}; - var ids = []; - var startOrder = templateInstance.collection.findOne(itemId)[orderField]; - if (orderPrevItem !== null) { - // Element has a previous sibling, therefore it was moved down in the list. - // Decrease the order of intervening elements. - selector[orderField] = {$lte: orderPrevItem, $gt: startOrder}; - ids = _.pluck(templateInstance.collection.find(selector, {fields: {_id: 1}}).fetch(), '_id'); - Meteor.call('rubaxa:sortable/collection-update', templateInstance.collectionName, ids, orderField, -1); - - // Set the order of the dropped element to the order of its predecessor, whose order was decreased - modifier.$set[orderField] = orderPrevItem; - } else { - // element moved up the list, increase order of intervening elements - selector[orderField] = {$gte: orderNextItem, $lt: startOrder}; - ids = _.pluck(templateInstance.collection.find(selector, {fields: {_id: 1}}).fetch(), '_id'); - Meteor.call('rubaxa:sortable/collection-update', templateInstance.collectionName, ids, orderField, 1); - - // Set the order of the dropped element to the order of its successor, whose order was increased - modifier.$set[orderField] = orderNextItem; - } - templateInstance.collection.update(itemId, modifier); - }; - - templateInstance.setupDone = true; -}; - - -Template.sortable.rendered = function () { - var templateInstance = this; - var orderField = templateInstance.options.sortField; - - // sorting was changed within the list - var optionsOnUpdate = templateInstance.options.onUpdate; - templateInstance.options.onUpdate = function sortableUpdate(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - if (event.newIndex < event.oldIndex) { - // Element moved up in the list. The dropped element has a next sibling for sure. - var orderNextItem = Blaze.getData(itemEl.nextElementSibling)[orderField]; - templateInstance.adjustOrders(event.data._id, null, orderNextItem); - } else if (event.newIndex > event.oldIndex) { - // Element moved down in the list. The dropped element has a previous sibling for sure. - var orderPrevItem = Blaze.getData(itemEl.previousElementSibling)[orderField]; - templateInstance.adjustOrders(event.data._id, orderPrevItem, null); - } else { - // do nothing - drag and drop in the same location - } - if (optionsOnUpdate) optionsOnUpdate(event); - }; - - // element was added from another list - var optionsOnAdd = templateInstance.options.onAdd; - templateInstance.options.onAdd = function sortableAdd(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - // let the user decorate the object with additional properties before insertion - if (optionsOnAdd) optionsOnAdd(event); - - // Insert the new element at the end of the list and move it where it was dropped. - // We could insert it at the beginning, but that would lead to negative orders. - var sortSpecifier = {}; sortSpecifier[orderField] = -1; - event.data.order = templateInstance.collection.findOne({}, { sort: sortSpecifier, limit: 1 }).order + 1; - // TODO: this can obviously be optimized by setting the order directly as the arithmetic average, with the caveats described above - var newElementId = templateInstance.collection.insert(event.data); - event.data._id = newElementId; - if (itemEl.nextElementSibling) { - var orderNextItem = Blaze.getData(itemEl.nextElementSibling)[orderField]; - templateInstance.adjustOrders(newElementId, null, orderNextItem); - } else { - // do nothing - inserted after the last element - } - // remove the dropped HTMLElement from the list because we have inserted it in the collection, which will update the template - itemEl.parentElement.removeChild(itemEl); - }; - - // element was removed by dragging into another list - var optionsOnRemove = templateInstance.options.onRemove; - templateInstance.options.onRemove = function sortableRemove(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - // don't remove from the collection if group.pull is clone or false - if (typeof templateInstance.options.group === 'undefined' - || typeof templateInstance.options.group.pull === 'undefined' - || templateInstance.options.group.pull === true - ) templateInstance.collection.remove(event.data._id); - if (optionsOnRemove) optionsOnRemove(event); - }; - - // just compute the `data` context - ['onStart', 'onEnd', 'onSort', 'onFilter'].forEach(function (eventHandler) { - if (templateInstance.options[eventHandler]) { - var userEventHandler = templateInstance.options[eventHandler]; - templateInstance.options[eventHandler] = function (/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - userEventHandler(event); - }; - } - }); - - templateInstance.sortable = Sortable.create(templateInstance.firstNode.parentElement, templateInstance.options); - // TODO make the object accessible, e.g. via Sortable.getSortableById() or some such -}; - - -Template.sortable.destroyed = function () { - this.sortable.destroy(); -}; diff --git a/meteor/runtests.sh b/meteor/runtests.sh deleted file mode 100755 index 94aaecf05..000000000 --- a/meteor/runtests.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# Test Meteor package before publishing to Atmospherejs.com - -# Make sure Meteor is installed, per https://www.meteor.com/install. -# The curl'ed script is totally safe; takes 2 minutes to read its source and check. -type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } - -# sanity check: make sure we're in the root directory of the checkout -cd "$( dirname "$0" )/.." - - -# delete the temporary files even if Ctrl+C is pressed -int_trap() { - printf "\nTests interrupted. Cleaning up...\n\n" -} -trap int_trap INT - - -ALL_EXIT_CODE=0 - -# test any package*.js packages we may have, e.g. package.js, package-standalone.js -for PACKAGE_FILE in meteor/package*.js; do - - # Meteor expects package.js in the root dir of the checkout, so copy there our package file under that name, temporarily - cp $PACKAGE_FILE ./package.js - - PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) - - echo "### Testing $PACKAGE_NAME..." - - # provide an invalid MONGO_URL so Meteor doesn't bog us down with an empty Mongo database - if [ $# -gt 0 ]; then - # interpret any parameter to mean we want an interactive test - MONGO_URL=mongodb:// meteor test-packages ./ - else - # automated/CI test with phantomjs - ./node_modules/.bin/spacejam --mongo-url mongodb:// test-packages ./ - ALL_EXIT_CODES=$(( $ALL_EXIT_CODES + $? )) - fi - - # delete temporary build files and package.js - rm -rf .build.* versions.json package.js - -done - -exit $ALL_EXIT_CODES diff --git a/meteor/template.html b/meteor/template.html deleted file mode 100644 index 3923d3d9c..000000000 --- a/meteor/template.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/meteor/test.js b/meteor/test.js deleted file mode 100644 index f7c00a9fb..000000000 --- a/meteor/test.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -Tinytest.add('Sortable.is', function (test) { - var items = document.createElement('ul'); - items.innerHTML = '
  • item 1
  • item 2
  • item 3
  • '; - var sortable = new Sortable(items); - test.instanceOf(sortable, Sortable, 'Instantiation OK'); - test.length(sortable.toArray(), 3, 'Three elements'); -}); From 70e469b574e9e5ae97f3604870c0203dcf8c847e Mon Sep 17 00:00:00 2001 From: RubaXa Date: Sun, 18 Jan 2015 21:55:53 +0300 Subject: [PATCH 02/41] #209: * drag-handle --- st/app.css | 1 + 1 file changed, 1 insertion(+) diff --git a/st/app.css b/st/app.css index 4dbbb8bdc..2059294f8 100644 --- a/st/app.css +++ b/st/app.css @@ -220,6 +220,7 @@ img { margin-right: 10px; font: bold 20px Sans-Serif; color: #5F9EDF; + display: inline-block; cursor: move; cursor: -webkit-grabbing; /* overrides 'move' */ } From 6db72617b888e20b27810a34d35273d559ba42b8 Mon Sep 17 00:00:00 2001 From: RubaXa Date: Tue, 27 Jan 2015 23:48:28 +0300 Subject: [PATCH 03/41] + meteor --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 434cfa9b1..f03de185a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ mock.png .*.sw* .build* jquery.fn.* +meteor From 19b103132d5e7912be55999d39c2a1a5ccc84f23 Mon Sep 17 00:00:00 2001 From: RubaXa Date: Fri, 4 Sep 2015 20:26:42 +0300 Subject: [PATCH 04/41] + min-height --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index c7064436e..ebe40685d 100644 --- a/index.html +++ b/index.html @@ -196,7 +196,7 @@

    The JavaScript library for modern browser
    {{remaining()}} of {{todos.length}} remaining -
      +
      • {{todo.text}} From 44c2b687583b71d713c3edafec137ceed6b326d4 Mon Sep 17 00:00:00 2001 From: RubaXa Date: Mon, 7 Sep 2015 13:52:23 +0300 Subject: [PATCH 05/41] #538: * preventDefault only if 'active' --- Sortable.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sortable.js b/Sortable.js index 9a24f6e97..216b714e0 100644 --- a/Sortable.js +++ b/Sortable.js @@ -665,8 +665,10 @@ this._offUpEvents(); if (evt) { - evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); + if (Sortable.active) { + evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } ghostEl && ghostEl.parentNode.removeChild(ghostEl); From dc5794860975f62f602d5ee6a28755f3108f3107 Mon Sep 17 00:00:00 2001 From: RubaXa Date: Thu, 10 Sep 2015 09:44:35 +0300 Subject: [PATCH 06/41] * upd --- Sortable.js | 294 ++++++++++++++++++++++++++-------------- Sortable.min.js | 4 +- jquery.binding.js | 7 +- knockout-sortable.js | 27 +++- ng-sortable.js | 79 ++++++----- react-sortable-mixin.js | 5 +- 6 files changed, 265 insertions(+), 151 deletions(-) diff --git a/Sortable.js b/Sortable.js index 216b714e0..6f5c9c9af 100644 --- a/Sortable.js +++ b/Sortable.js @@ -25,6 +25,7 @@ "use strict"; var dragEl, + parentEl, ghostEl, cloneEl, rootEl, @@ -35,6 +36,7 @@ lastEl, lastCSS, + lastParentCSS, oldIndex, newIndex, @@ -45,6 +47,8 @@ tapEvt, touchEvt, + moved, + /** @const */ RSPACE = /\s+/g, @@ -55,6 +59,11 @@ parseInt = win.parseInt, supportDraggable = !!('draggable' in document.createElement('div')), + supportCssPointerEvents = (function (el) { + el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + })(), _silent = false, @@ -136,7 +145,23 @@ } } } - }, 30) + }, 30), + + _prepareGroup = function (options) { + var group = options.group; + + if (!group || typeof group != 'object') { + group = options.group = {name: group}; + } + + ['pull', 'put'].forEach(function (key) { + if (!(key in group)) { + group[key] = true; + } + }); + + options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' '; + } ; @@ -167,6 +192,7 @@ scrollSpeed: 10, draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', ignore: 'a, img', filter: null, animation: 0, @@ -176,7 +202,10 @@ dropBubble: false, dragoverBubble: false, dataIdAttr: 'data-id', - delay: 0 + delay: 0, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false }; @@ -185,38 +214,26 @@ !(name in options) && (options[name] = defaults[name]); } - - var group = options.group; - - if (!group || typeof group != 'object') { - group = options.group = { name: group }; - } - - - ['pull', 'put'].forEach(function (key) { - if (!(key in group)) { - group[key] = true; - } - }); - - - options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' '; - + _prepareGroup(options); // Bind all private methods for (var fn in this) { if (fn.charAt(0) === '_') { - this[fn] = _bind(this, this[fn]); + this[fn] = this[fn].bind(this); } } + // Setup drag mode + this.nativeDraggable = options.forceFallback ? false : supportDraggable; // Bind events _on(el, 'mousedown', this._onTapStart); _on(el, 'touchstart', this._onTapStart); - _on(el, 'dragover', this); - _on(el, 'dragenter', this); + if (this.nativeDraggable) { + _on(el, 'dragover', this); + _on(el, 'dragenter', this); + } touchDragOverListeners.push(this._onDragOver); @@ -298,6 +315,7 @@ rootEl = el; dragEl = target; + parentEl = dragEl.parentNode; nextEl = dragEl.nextSibling; activeGroup = options.group; @@ -309,22 +327,29 @@ // Make the element draggable dragEl.draggable = true; - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - _find(dragEl, criteria.trim(), _disableDraggable); - }); + // Chosen item + _toggleClass(dragEl, _this.options.chosenClass, true); // Bind the events: dragstart/dragend _this._triggerDragStart(touch); }; + // Disable "draggable" + options.ignore.split(',').forEach(function (criteria) { + _find(dragEl, criteria.trim(), _disableDraggable); + }); + _on(ownerDocument, 'mouseup', _this._onDrop); _on(ownerDocument, 'touchend', _this._onDrop); _on(ownerDocument, 'touchcancel', _this._onDrop); if (options.delay) { - // If the user moves the pointer before the delay has been reached: + // If the user moves the pointer or let go the click or touch + // before the delay has been reached: // disable the delayed drag + _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + _on(ownerDocument, 'touchend', _this._disableDelayedDrag); + _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); @@ -339,7 +364,9 @@ var ownerDocument = this.el.ownerDocument; clearTimeout(this._dragStartTimer); - + _off(ownerDocument, 'mouseup', this._disableDelayedDrag); + _off(ownerDocument, 'touchend', this._disableDelayedDrag); + _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); _off(ownerDocument, 'mousemove', this._disableDelayedDrag); _off(ownerDocument, 'touchmove', this._disableDelayedDrag); }, @@ -355,7 +382,7 @@ this._onDragStart(tapEvt, 'touch'); } - else if (!supportDraggable) { + else if (!this.nativeDraggable) { this._onDragStart(tapEvt, true); } else { @@ -387,7 +414,16 @@ _emulateDragOver: function () { if (touchEvt) { - _css(ghostEl, 'display', 'none'); + if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { + return; + } + + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', 'none'); + } var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY), parent = target, @@ -415,18 +451,29 @@ while (parent = parent.parentNode); } - _css(ghostEl, 'display', ''); + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', ''); + } } }, _onTouchMove: function (/**TouchEvent*/evt) { if (tapEvt) { + // only set the status to dragging, when we are actually dragging + if (!Sortable.active) { + this._dragStarted(); + } + + // as well as creating the ghost element on the document body + this._appendGhost(); + var touch = evt.touches ? evt.touches[0] : evt, dx = touch.clientX - tapEvt.clientX, dy = touch.clientY - tapEvt.clientY, translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; + moved = true; touchEvt = touch; _css(ghostEl, 'webkitTransform', translate3d); @@ -438,26 +485,17 @@ } }, - - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var dataTransfer = evt.dataTransfer, - options = this.options; - - this._offUpEvents(); - - if (activeGroup.pull == 'clone') { - cloneEl = dragEl.cloneNode(true); - _css(cloneEl, 'display', 'none'); - rootEl.insertBefore(cloneEl, dragEl); - } - - if (useFallback) { + _appendGhost: function () { + if (!ghostEl) { var rect = dragEl.getBoundingClientRect(), css = _css(dragEl), ghostRect; ghostEl = dragEl.cloneNode(true); + _toggleClass(ghostEl, this.options.ghostClass, false); + _toggleClass(ghostEl, this.options.fallbackClass, true); + _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); _css(ghostEl, 'width', rect.width); @@ -465,13 +503,30 @@ _css(ghostEl, 'opacity', '0.8'); _css(ghostEl, 'position', 'fixed'); _css(ghostEl, 'zIndex', '100000'); + _css(ghostEl, 'pointerEvents', 'none'); - rootEl.appendChild(ghostEl); + this.options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); // Fixing dimensions. ghostRect = ghostEl.getBoundingClientRect(); _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); + } + }, + + _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { + var dataTransfer = evt.dataTransfer, + options = this.options; + + this._offUpEvents(); + + if (activeGroup.pull == 'clone') { + cloneEl = dragEl.cloneNode(true); + _css(cloneEl, 'display', 'none'); + rootEl.insertBefore(cloneEl, dragEl); + } + + if (useFallback) { if (useFallback === 'touch') { // Bind touch events @@ -484,7 +539,7 @@ _on(document, 'mouseup', this._onDrop); } - this._loopId = setInterval(this._emulateDragOver, 150); + this._loopId = setInterval(this._emulateDragOver, 50); } else { if (dataTransfer) { @@ -493,9 +548,8 @@ } _on(document, 'drop', this); + setTimeout(this._dragStarted, 0); } - - setTimeout(this._dragStarted, 0); }, _onDragOver: function (/**Event*/evt) { @@ -514,6 +568,8 @@ !options.dragoverBubble && evt.stopPropagation(); } + moved = true; + if (activeGroup && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list @@ -534,7 +590,6 @@ target = _closest(evt.target, options.draggable, el); dragRect = dragEl.getBoundingClientRect(); - if (revert) { _cloneHide(true); @@ -550,19 +605,25 @@ if ((el.children.length === 0) || (el.children[0] === ghostEl) || - (el === evt.target) && (target = _ghostInBottom(el, evt)) + (el === evt.target) && (target = _ghostIsLast(el, evt)) ) { + if (target) { if (target.animated) { return; } + targetRect = target.getBoundingClientRect(); } _cloneHide(isOwner); if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) { - el.appendChild(dragEl); + if (!dragEl.contains(el)) { + el.appendChild(dragEl); + parentEl = el; // actualization + } + this._animate(dragRect, dragEl); target && this._animate(targetRect, target); } @@ -571,13 +632,15 @@ if (lastEl !== target) { lastEl = target; lastCSS = _css(target); + lastParentCSS = _css(target.parentNode); } var targetRect = target.getBoundingClientRect(), width = targetRect.right - targetRect.left, height = targetRect.bottom - targetRect.top, - floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display), + floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display) + || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), isWide = (target.offsetWidth > dragEl.offsetWidth), isLong = (target.offsetHeight > dragEl.offsetHeight), halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, @@ -596,17 +659,28 @@ after = (moveVector === 1); } else if (floating) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; + var elTop = dragEl.offsetTop, + tgTop = target.offsetTop; + + if (elTop === tgTop) { + after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; + } else { + after = tgTop > elTop; + } } else { after = (nextSibling !== dragEl) && !isLong || halfway && isLong; } - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + if (!dragEl.contains(el)) { + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } } + parentEl = dragEl.parentNode; // actualization + this._animate(dragRect, dragEl); this._animate(targetRect, target); } @@ -658,14 +732,17 @@ clearTimeout(this._dragStartTimer); // Unbind events - _off(document, 'drop', this); _off(document, 'mousemove', this._onTouchMove); - _off(el, 'dragstart', this._onDragStart); + + if (this.nativeDraggable) { + _off(document, 'drop', this); + _off(el, 'dragstart', this._onDragStart); + } this._offUpEvents(); if (evt) { - if (Sortable.active) { + if (moved) { evt.preventDefault(); !options.dropBubble && evt.stopPropagation(); } @@ -673,23 +750,30 @@ ghostEl && ghostEl.parentNode.removeChild(ghostEl); if (dragEl) { - _off(dragEl, 'dragend', this); + if (this.nativeDraggable) { + _off(dragEl, 'dragend', this); + } _disableDraggable(dragEl); + + // Remove class's _toggleClass(dragEl, this.options.ghostClass, false); + _toggleClass(dragEl, this.options.chosenClass, false); - if (rootEl !== dragEl.parentNode) { + if (rootEl !== parentEl) { newIndex = _index(dragEl); - // drag from one list and drop into another - _dispatchEvent(null, dragEl.parentNode, 'sort', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + if (newIndex != -1) { + // drag from one list and drop into another + _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - // Add event - _dispatchEvent(null, dragEl.parentNode, 'add', dragEl, rootEl, oldIndex, newIndex); + // Add event + _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex); - // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex); + // Remove event + _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex); + } } else { // Remove clone @@ -698,10 +782,11 @@ if (dragEl.nextSibling !== nextEl) { // Get the index of the dragged element within its parent newIndex = _index(dragEl); - - // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + if (newIndex != -1) { + // drag & drop within the same list + _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + } } } @@ -717,6 +802,7 @@ // Nulling rootEl = dragEl = + parentEl = ghostEl = nextEl = cloneEl = @@ -727,6 +813,9 @@ tapEvt = touchEvt = + moved = + newIndex = + lastEl = lastCSS = @@ -831,6 +920,10 @@ return options[name]; } else { options[name] = value; + + if (name === 'group') { + _prepareGroup(options); + } } }, @@ -846,8 +939,10 @@ _off(el, 'mousedown', this._onTapStart); _off(el, 'touchstart', this._onTapStart); - _off(el, 'dragover', this); - _off(el, 'dragenter', this); + if (this.nativeDraggable) { + _off(el, 'dragover', this); + _off(el, 'dragenter', this); + } // Remove draggable attributes Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { @@ -872,14 +967,6 @@ } - function _bind(ctx, fn) { - var args = slice.call(arguments, 2); - return fn.bind ? fn.bind.apply(fn, [ctx].concat(args)) : function () { - return fn.apply(ctx, args.concat(slice.call(arguments))); - }; - } - - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { if (el) { ctx = ctx || document; @@ -906,7 +993,9 @@ function _globalDragOver(/**Event*/evt) { - evt.dataTransfer.dropEffect = 'move'; + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } evt.preventDefault(); } @@ -1006,17 +1095,19 @@ onMoveFn = sortable.options.onMove, retVal; - if (onMoveFn) { - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + fromEl.dispatchEvent(evt); + + if (onMoveFn) { retVal = onMoveFn.call(sortable, evt); } @@ -1035,11 +1126,11 @@ /** @returns {HTMLElement|false} */ - function _ghostInBottom(el, evt) { + function _ghostIsLast(el, evt) { var lastEl = el.lastElementChild, - rect = lastEl.getBoundingClientRect(); + rect = lastEl.getBoundingClientRect(); - return (evt.clientY - (rect.top + rect.height) > 5) && lastEl; // min delta + return ((evt.clientY - (rect.top + rect.height) > 5) || (evt.clientX - (rect.right + rect.width) > 5)) && lastEl; // min delta } @@ -1068,6 +1159,9 @@ * @private */ function _index(/**HTMLElement*/el) { + if (!el || !el.parentNode) { + return -1; + } var index = 0; while (el && (el = el.previousElementSibling)) { if (el.nodeName.toUpperCase() !== 'TEMPLATE') { @@ -1117,7 +1211,6 @@ off: _off, css: _css, find: _find, - bind: _bind, is: function (el, selector) { return !!_closest(el, selector, el); }, @@ -1129,9 +1222,6 @@ }; - Sortable.version = '1.2.1'; - - /** * Create sortable instance * @param {HTMLElement} el @@ -1141,6 +1231,8 @@ return new Sortable(el, options); }; + // Export + Sortable.version = '1.3.0-rc1'; return Sortable; }); diff --git a/Sortable.min.js b/Sortable.min.js index 754718913..5a90378de 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.2.1 - MIT | git://github.com/rubaxa/Sortable.git */ -!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){this.el=a,this.options=b=s({},b),a[J]=this;var d={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0};for(var e in d)!(e in b)&&(b[e]=d[e]);var g=b.group;g&&"object"==typeof g||(g=b.group={name:g}),["pull","put"].forEach(function(a){a in g||(g[a]=!0)}),b.groups=" "+g.name+(g.put.join?" "+g.put.join(" "):"")+" ";for(var h in this)"_"===h.charAt(0)&&(this[h]=c(this,this[h]));f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),f(a,"dragover",this),f(a,"dragenter",this),R.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){v&&v.state!==a&&(i(v,"display",a?"none":""),!a&&v.state&&w.insertBefore(v,t),v.state=a)}function c(a,b){var c=Q.call(arguments,2);return b.bind?b.bind.apply(b,[a].concat(c)):function(){return b.apply(a,c.concat(Q.call(arguments)))}}function d(a,b,c){if(a){c=c||L,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")(?=\\s)","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function e(a){a.dataTransfer.dropEffect="move",a.preventDefault()}function f(a,b,c){a.addEventListener(b,c,!1)}function g(a,b,c){a.removeEventListener(b,c,!1)}function h(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(I," ").replace(" "+b+" "," ");a.className=(d+(c?" "+b:"")).replace(I," ")}}function i(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return L.defaultView&&L.defaultView.getComputedStyle?c=L.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function j(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function k(a,b,c,d,e,f,g){var h=L.createEvent("Event"),i=(a||b[J]).options,j="on"+c.charAt(0).toUpperCase()+c.substr(1);h.initEvent(c,!0,!0),h.to=b,h.from=e||b,h.item=d||b,h.clone=v,h.oldIndex=f,h.newIndex=g,b.dispatchEvent(h),i[j]&&i[j].call(a,h)}function l(a,b,c,d,e,f){var g,h,i=a[J],j=i.options.onMove;return j&&(g=L.createEvent("Event"),g.initEvent("move",!0,!0),g.to=b,g.from=a,g.dragged=c,g.draggedRect=d,g.related=e||b,g.relatedRect=f||b.getBoundingClientRect(),h=j.call(i,g)),h}function m(a){a.draggable=!1}function n(){O=!1}function o(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return b.clientY-(d.top+d.height)>5&&c}function p(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function q(a){for(var b=0;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function r(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}function s(a,b){if(a&&b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}var t,u,v,w,x,y,z,A,B,C,D,E,F,G,H={},I=/\s+/g,J="Sortable"+(new Date).getTime(),K=window,L=K.document,M=K.parseInt,N=!!("draggable"in L.createElement("div")),O=!1,P=Math.abs,Q=[].slice,R=[],S=r(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(z!==c&&(y=b.scroll,z=c,y===!0)){y=c;do if(y.offsetWidth=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=K)),(H.vx!==f||H.vy!==g||H.el!==d)&&(H.el=d,H.vx=f,H.vy=g,clearInterval(H.pid),d&&(H.pid=setInterval(function(){d===K?K.scrollTo(K.pageXOffset+f*i,K.pageYOffset+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30);return a.prototype={constructor:a,_onTapStart:function(a){var b=this,c=this.el,e=this.options,f=a.type,g=a.touches&&a.touches[0],h=(g||a).target,i=h,j=e.filter;if(!("mousedown"===f&&0!==a.button||e.disabled)&&(h=d(h,e.draggable,c))){if(C=q(h),"function"==typeof j){if(j.call(this,a,h,this))return k(b,i,"filter",h,c,C),void a.preventDefault()}else if(j&&(j=j.split(",").some(function(a){return a=d(i,a.trim(),c),a?(k(b,a,"filter",h,c,C),!0):void 0})))return void a.preventDefault();(!e.handle||d(i,e.handle,c))&&this._prepareDragStart(a,g,h)}},_prepareDragStart:function(a,b,c){var d,e=this,g=e.el,h=e.options,i=g.ownerDocument;c&&!t&&c.parentNode===g&&(F=a,w=g,t=c,x=t.nextSibling,E=h.group,d=function(){e._disableDelayedDrag(),t.draggable=!0,h.ignore.split(",").forEach(function(a){j(t,a.trim(),m)}),e._triggerDragStart(b)},f(i,"mouseup",e._onDrop),f(i,"touchend",e._onDrop),f(i,"touchcancel",e._onDrop),h.delay?(f(i,"mousemove",e._disableDelayedDrag),f(i,"touchmove",e._disableDelayedDrag),e._dragStartTimer=setTimeout(d,h.delay)):d())},_disableDelayedDrag:function(){var a=this.el.ownerDocument;clearTimeout(this._dragStartTimer),g(a,"mousemove",this._disableDelayedDrag),g(a,"touchmove",this._disableDelayedDrag)},_triggerDragStart:function(a){a?(F={target:t,clientX:a.clientX,clientY:a.clientY},this._onDragStart(F,"touch")):N?(f(t,"dragend",this),f(w,"dragstart",this._onDragStart)):this._onDragStart(F,!0);try{L.selection?L.selection.empty():window.getSelection().removeAllRanges()}catch(b){}},_dragStarted:function(){w&&t&&(h(t,this.options.ghostClass,!0),a.active=this,k(this,w,"start",t,w,C))},_emulateDragOver:function(){if(G){i(u,"display","none");var a=L.elementFromPoint(G.clientX,G.clientY),b=a,c=" "+this.options.group.name,d=R.length;if(b)do{if(b[J]&&b[J].options.groups.indexOf(c)>-1){for(;d--;)R[d]({clientX:G.clientX,clientY:G.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);i(u,"display","")}},_onTouchMove:function(a){if(F){var b=a.touches?a.touches[0]:a,c=b.clientX-F.clientX,d=b.clientY-F.clientY,e=a.touches?"translate3d("+c+"px,"+d+"px,0)":"translate("+c+"px,"+d+"px)";G=b,i(u,"webkitTransform",e),i(u,"mozTransform",e),i(u,"msTransform",e),i(u,"transform",e),a.preventDefault()}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;if(this._offUpEvents(),"clone"==E.pull&&(v=t.cloneNode(!0),i(v,"display","none"),w.insertBefore(v,t)),b){var e,g=t.getBoundingClientRect(),h=i(t);u=t.cloneNode(!0),i(u,"top",g.top-M(h.marginTop,10)),i(u,"left",g.left-M(h.marginLeft,10)),i(u,"width",g.width),i(u,"height",g.height),i(u,"opacity","0.8"),i(u,"position","fixed"),i(u,"zIndex","100000"),w.appendChild(u),e=u.getBoundingClientRect(),i(u,"width",2*g.width-e.width),i(u,"height",2*g.height-e.height),"touch"===b?(f(L,"touchmove",this._onTouchMove),f(L,"touchend",this._onDrop),f(L,"touchcancel",this._onDrop)):(f(L,"mousemove",this._onTouchMove),f(L,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,150)}else c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,t)),f(L,"drop",this);setTimeout(this._dragStarted,0)},_onDragOver:function(a){var c,e,f,g=this.el,h=this.options,j=h.group,k=j.put,m=E===j,p=h.sort;if(void 0!==a.preventDefault&&(a.preventDefault(),!h.dragoverBubble&&a.stopPropagation()),E&&!h.disabled&&(m?p||(f=!w.contains(t)):E.pull&&k&&(E.name===j.name||k.indexOf&&~k.indexOf(E.name)))&&(void 0===a.rootEl||a.rootEl===this.el)){if(S(a,h,this.el),O)return;if(c=d(a.target,h.draggable,g),e=t.getBoundingClientRect(),f)return b(!0),void(v||x?w.insertBefore(t,v||x):p||w.appendChild(t));if(0===g.children.length||g.children[0]===u||g===a.target&&(c=o(g,a))){if(c){if(c.animated)return;r=c.getBoundingClientRect()}b(m),l(w,g,t,e,c,r)!==!1&&(g.appendChild(t),this._animate(e,t),c&&this._animate(r,c))}else if(c&&!c.animated&&c!==t&&void 0!==c.parentNode[J]){A!==c&&(A=c,B=i(c));var q,r=c.getBoundingClientRect(),s=r.right-r.left,y=r.bottom-r.top,z=/left|right|inline/.test(B.cssFloat+B.display),C=c.offsetWidth>t.offsetWidth,D=c.offsetHeight>t.offsetHeight,F=(z?(a.clientX-r.left)/s:(a.clientY-r.top)/y)>.5,G=c.nextElementSibling,H=l(w,g,t,e,c,r);H!==!1&&(O=!0,setTimeout(n,30),b(m),q=1===H||-1===H?1===H:z?c.previousElementSibling===t&&!C||F&&C:G!==t&&!D||F&&D,q&&!G?g.appendChild(t):c.parentNode.insertBefore(t,q?G:c),this._animate(e,t),this._animate(r,c))}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();i(b,"transition","none"),i(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,i(b,"transition","all "+c+"ms"),i(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){i(b,"transition",""),i(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){var a=this.el.ownerDocument;g(L,"touchmove",this._onTouchMove),g(a,"mouseup",this._onDrop),g(a,"touchend",this._onDrop),g(a,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(H.pid),clearTimeout(this._dragStartTimer),g(L,"drop",this),g(L,"mousemove",this._onTouchMove),g(c,"dragstart",this._onDragStart),this._offUpEvents(),b&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation(),u&&u.parentNode.removeChild(u),t&&(g(t,"dragend",this),m(t),h(t,this.options.ghostClass,!1),w!==t.parentNode?(D=q(t),k(null,t.parentNode,"sort",t,w,C,D),k(this,w,"sort",t,w,C,D),k(null,t.parentNode,"add",t,w,C,D),k(this,w,"remove",t,w,C,D)):(v&&v.parentNode.removeChild(v),t.nextSibling!==x&&(D=q(t),k(this,w,"update",t,w,C,D),k(this,w,"sort",t,w,C,D))),a.active&&(k(this,w,"end",t,w,C,D),this.save())),w=t=u=x=v=y=z=F=G=A=B=E=a.active=null)},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?t&&(this._onDragOver(a),e(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],c=this.el.children,e=0,f=c.length,g=this.options;f>e;e++)a=c[e],d(a,g.draggable,this.el)&&b.push(a.getAttribute(g.dataIdAttr)||p(a));return b},sort:function(a){var b={},c=this.el;this.toArray().forEach(function(a,e){var f=c.children[e];d(f,this.options.draggable,c)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(c.removeChild(b[a]),c.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return d(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:void(c[a]=b)},destroy:function(){var a=this.el;a[J]=null,g(a,"mousedown",this._onTapStart),g(a,"touchstart",this._onTapStart),g(a,"dragover",this),g(a,"dragenter",this),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),R.splice(R.indexOf(this._onDragOver),1),this._onDrop(),this.el=a=null}},a.utils={on:f,off:g,css:i,find:j,bind:c,is:function(a,b){return!!d(a,b,a)},extend:s,throttle:r,closest:d,toggleClass:h,index:q},a.version="1.2.1",a.create=function(b,c){return new a(b,c)},a}); \ No newline at end of file +/*! Sortable 1.3.0-rc1 - MIT | git://github.com/rubaxa/Sortable.git */ +!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():"undefined"!=typeof Package?Sortable=a():window.Sortable=a()}(function(){"use strict";function a(a,b){this.el=a,this.options=b=r({},b),a[L]=this;var c={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",ignore:"a, img",filter:null,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1};for(var d in c)!(d in b)&&(b[d]=c[d]);V(b);for(var f in this)"_"===f.charAt(0)&&(this[f]=this[f].bind(this));this.nativeDraggable=b.forceFallback?!1:P,e(a,"mousedown",this._onTapStart),e(a,"touchstart",this._onTapStart),this.nativeDraggable&&(e(a,"dragover",this),e(a,"dragenter",this)),T.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a){v&&v.state!==a&&(h(v,"display",a?"none":""),!a&&v.state&&w.insertBefore(v,s),v.state=a)}function c(a,b,c){if(a){c=c||N,b=b.split(".");var d=b.shift().toUpperCase(),e=new RegExp("\\s("+b.join("|")+")(?=\\s)","g");do if(">*"===d&&a.parentNode===c||(""===d||a.nodeName.toUpperCase()==d)&&(!b.length||((" "+a.className+" ").match(e)||[]).length==b.length))return a;while(a!==c&&(a=a.parentNode))}return null}function d(a){a.dataTransfer&&(a.dataTransfer.dropEffect="move"),a.preventDefault()}function e(a,b,c){a.addEventListener(b,c,!1)}function f(a,b,c){a.removeEventListener(b,c,!1)}function g(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(K," ").replace(" "+b+" "," ");a.className=(d+(c?" "+b:"")).replace(K," ")}}function h(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return N.defaultView&&N.defaultView.getComputedStyle?c=N.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function i(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;f>e;e++)c(d[e],e);return d}return[]}function j(a,b,c,d,e,f,g){var h=N.createEvent("Event"),i=(a||b[L]).options,j="on"+c.charAt(0).toUpperCase()+c.substr(1);h.initEvent(c,!0,!0),h.to=b,h.from=e||b,h.item=d||b,h.clone=v,h.oldIndex=f,h.newIndex=g,b.dispatchEvent(h),i[j]&&i[j].call(a,h)}function k(a,b,c,d,e,f){var g,h,i=a[L],j=i.options.onMove;return g=N.createEvent("Event"),g.initEvent("move",!0,!0),g.to=b,g.from=a,g.dragged=c,g.draggedRect=d,g.related=e||b,g.relatedRect=f||b.getBoundingClientRect(),a.dispatchEvent(g),j&&(h=j.call(i,g)),h}function l(a){a.draggable=!1}function m(){R=!1}function n(a,b){var c=a.lastElementChild,d=c.getBoundingClientRect();return(b.clientY-(d.top+d.height)>5||b.clientX-(d.right+d.width)>5)&&c}function o(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function p(a){if(!a||!a.parentNode)return-1;for(var b=0;a&&(a=a.previousElementSibling);)"TEMPLATE"!==a.nodeName.toUpperCase()&&b++;return b}function q(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}function r(a,b){if(a&&b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}var s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J={},K=/\s+/g,L="Sortable"+(new Date).getTime(),M=window,N=M.document,O=M.parseInt,P=!!("draggable"in N.createElement("div")),Q=function(a){return a=N.createElement("x"),a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents}(),R=!1,S=Math.abs,T=([].slice,[]),U=q(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h=b.scrollSensitivity,i=b.scrollSpeed,j=a.clientX,k=a.clientY,l=window.innerWidth,m=window.innerHeight;if(z!==c&&(y=b.scroll,z=c,y===!0)){y=c;do if(y.offsetWidth=l-j)-(h>=j),g=(h>=m-k)-(h>=k),(f||g)&&(d=M)),(J.vx!==f||J.vy!==g||J.el!==d)&&(J.el=d,J.vx=f,J.vy=g,clearInterval(J.pid),d&&(J.pid=setInterval(function(){d===M?M.scrollTo(M.pageXOffset+f*i,M.pageYOffset+g*i):(g&&(d.scrollTop+=g*i),f&&(d.scrollLeft+=f*i))},24)))}},30),V=function(a){var b=a.group;b&&"object"==typeof b||(b=a.group={name:b}),["pull","put"].forEach(function(a){a in b||(b[a]=!0)}),a.groups=" "+b.name+(b.put.join?" "+b.put.join(" "):"")+" "};return a.prototype={constructor:a,_onTapStart:function(a){var b=this,d=this.el,e=this.options,f=a.type,g=a.touches&&a.touches[0],h=(g||a).target,i=h,k=e.filter;if(!("mousedown"===f&&0!==a.button||e.disabled)&&(h=c(h,e.draggable,d))){if(D=p(h),"function"==typeof k){if(k.call(this,a,h,this))return j(b,i,"filter",h,d,D),void a.preventDefault()}else if(k&&(k=k.split(",").some(function(a){return a=c(i,a.trim(),d),a?(j(b,a,"filter",h,d,D),!0):void 0})))return void a.preventDefault();(!e.handle||c(i,e.handle,d))&&this._prepareDragStart(a,g,h)}},_prepareDragStart:function(a,b,c){var d,f=this,h=f.el,j=f.options,k=h.ownerDocument;c&&!s&&c.parentNode===h&&(G=a,w=h,s=c,t=s.parentNode,x=s.nextSibling,F=j.group,d=function(){f._disableDelayedDrag(),s.draggable=!0,g(s,f.options.chosenClass,!0),f._triggerDragStart(b)},j.ignore.split(",").forEach(function(a){i(s,a.trim(),l)}),e(k,"mouseup",f._onDrop),e(k,"touchend",f._onDrop),e(k,"touchcancel",f._onDrop),j.delay?(e(k,"mouseup",f._disableDelayedDrag),e(k,"touchend",f._disableDelayedDrag),e(k,"touchcancel",f._disableDelayedDrag),e(k,"mousemove",f._disableDelayedDrag),e(k,"touchmove",f._disableDelayedDrag),f._dragStartTimer=setTimeout(d,j.delay)):d())},_disableDelayedDrag:function(){var a=this.el.ownerDocument;clearTimeout(this._dragStartTimer),f(a,"mouseup",this._disableDelayedDrag),f(a,"touchend",this._disableDelayedDrag),f(a,"touchcancel",this._disableDelayedDrag),f(a,"mousemove",this._disableDelayedDrag),f(a,"touchmove",this._disableDelayedDrag)},_triggerDragStart:function(a){a?(G={target:s,clientX:a.clientX,clientY:a.clientY},this._onDragStart(G,"touch")):this.nativeDraggable?(e(s,"dragend",this),e(w,"dragstart",this._onDragStart)):this._onDragStart(G,!0);try{N.selection?N.selection.empty():window.getSelection().removeAllRanges()}catch(b){}},_dragStarted:function(){w&&s&&(g(s,this.options.ghostClass,!0),a.active=this,j(this,w,"start",s,w,D))},_emulateDragOver:function(){if(H){if(this._lastX===H.clientX&&this._lastY===H.clientY)return;this._lastX=H.clientX,this._lastY=H.clientY,Q||h(u,"display","none");var a=N.elementFromPoint(H.clientX,H.clientY),b=a,c=" "+this.options.group.name,d=T.length;if(b)do{if(b[L]&&b[L].options.groups.indexOf(c)>-1){for(;d--;)T[d]({clientX:H.clientX,clientY:H.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);Q||h(u,"display","")}},_onTouchMove:function(b){if(G){a.active||this._dragStarted(),this._appendGhost();var c=b.touches?b.touches[0]:b,d=c.clientX-G.clientX,e=c.clientY-G.clientY,f=b.touches?"translate3d("+d+"px,"+e+"px,0)":"translate("+d+"px,"+e+"px)";I=!0,H=c,h(u,"webkitTransform",f),h(u,"mozTransform",f),h(u,"msTransform",f),h(u,"transform",f),b.preventDefault()}},_appendGhost:function(){if(!u){var a,b=s.getBoundingClientRect(),c=h(s);u=s.cloneNode(!0),g(u,this.options.ghostClass,!1),g(u,this.options.fallbackClass,!0),h(u,"top",b.top-O(c.marginTop,10)),h(u,"left",b.left-O(c.marginLeft,10)),h(u,"width",b.width),h(u,"height",b.height),h(u,"opacity","0.8"),h(u,"position","fixed"),h(u,"zIndex","100000"),h(u,"pointerEvents","none"),this.options.fallbackOnBody&&N.body.appendChild(u)||w.appendChild(u),a=u.getBoundingClientRect(),h(u,"width",2*b.width-a.width),h(u,"height",2*b.height-a.height)}},_onDragStart:function(a,b){var c=a.dataTransfer,d=this.options;this._offUpEvents(),"clone"==F.pull&&(v=s.cloneNode(!0),h(v,"display","none"),w.insertBefore(v,s)),b?("touch"===b?(e(N,"touchmove",this._onTouchMove),e(N,"touchend",this._onDrop),e(N,"touchcancel",this._onDrop)):(e(N,"mousemove",this._onTouchMove),e(N,"mouseup",this._onDrop)),this._loopId=setInterval(this._emulateDragOver,50)):(c&&(c.effectAllowed="move",d.setData&&d.setData.call(this,c,s)),e(N,"drop",this),setTimeout(this._dragStarted,0))},_onDragOver:function(a){var d,e,f,g=this.el,i=this.options,j=i.group,l=j.put,o=F===j,p=i.sort;if(void 0!==a.preventDefault&&(a.preventDefault(),!i.dragoverBubble&&a.stopPropagation()),I=!0,F&&!i.disabled&&(o?p||(f=!w.contains(s)):F.pull&&l&&(F.name===j.name||l.indexOf&&~l.indexOf(F.name)))&&(void 0===a.rootEl||a.rootEl===this.el)){if(U(a,i,this.el),R)return;if(d=c(a.target,i.draggable,g),e=s.getBoundingClientRect(),f)return b(!0),void(v||x?w.insertBefore(s,v||x):p||w.appendChild(s));if(0===g.children.length||g.children[0]===u||g===a.target&&(d=n(g,a))){if(d){if(d.animated)return;r=d.getBoundingClientRect()}b(o),k(w,g,s,e,d,r)!==!1&&(s.contains(g)||(g.appendChild(s),t=g),this._animate(e,s),d&&this._animate(r,d))}else if(d&&!d.animated&&d!==s&&void 0!==d.parentNode[L]){A!==d&&(A=d,B=h(d),C=h(d.parentNode));var q,r=d.getBoundingClientRect(),y=r.right-r.left,z=r.bottom-r.top,D=/left|right|inline/.test(B.cssFloat+B.display)||"flex"==C.display&&0===C["flex-direction"].indexOf("row"),E=d.offsetWidth>s.offsetWidth,G=d.offsetHeight>s.offsetHeight,H=(D?(a.clientX-r.left)/y:(a.clientY-r.top)/z)>.5,J=d.nextElementSibling,K=k(w,g,s,e,d,r);if(K!==!1){if(R=!0,setTimeout(m,30),b(o),1===K||-1===K)q=1===K;else if(D){var M=s.offsetTop,N=d.offsetTop;q=M===N?d.previousElementSibling===s&&!E||H&&E:N>M}else q=J!==s&&!G||H&&G;s.contains(g)||(q&&!J?g.appendChild(s):d.parentNode.insertBefore(s,q?J:d)),t=s.parentNode,this._animate(e,s),this._animate(r,d)}}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();h(b,"transition","none"),h(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,h(b,"transition","all "+c+"ms"),h(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){h(b,"transition",""),h(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){var a=this.el.ownerDocument;f(N,"touchmove",this._onTouchMove),f(a,"mouseup",this._onDrop),f(a,"touchend",this._onDrop),f(a,"touchcancel",this._onDrop)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(J.pid),clearTimeout(this._dragStartTimer),f(N,"mousemove",this._onTouchMove),this.nativeDraggable&&(f(N,"drop",this),f(c,"dragstart",this._onDragStart)),this._offUpEvents(),b&&(I&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation()),u&&u.parentNode.removeChild(u),s&&(this.nativeDraggable&&f(s,"dragend",this),l(s),g(s,this.options.ghostClass,!1),g(s,this.options.chosenClass,!1),w!==t?(E=p(s),-1!=E&&(j(null,t,"sort",s,w,D,E),j(this,w,"sort",s,w,D,E),j(null,t,"add",s,w,D,E),j(this,w,"remove",s,w,D,E))):(v&&v.parentNode.removeChild(v),s.nextSibling!==x&&(E=p(s),-1!=E&&(j(this,w,"update",s,w,D,E),j(this,w,"sort",s,w,D,E)))),a.active&&(j(this,w,"end",s,w,D,E),this.save())),w=s=t=u=x=v=y=z=G=H=I=E=A=B=F=a.active=null)},handleEvent:function(a){var b=a.type;"dragover"===b||"dragenter"===b?s&&(this._onDragOver(a),d(a)):("drop"===b||"dragend"===b)&&this._onDrop(a)},toArray:function(){for(var a,b=[],d=this.el.children,e=0,f=d.length,g=this.options;f>e;e++)a=d[e],c(a,g.draggable,this.el)&&b.push(a.getAttribute(g.dataIdAttr)||o(a));return b},sort:function(a){var b={},d=this.el;this.toArray().forEach(function(a,e){var f=d.children[e];c(f,this.options.draggable,d)&&(b[a]=f)},this),a.forEach(function(a){b[a]&&(d.removeChild(b[a]),d.appendChild(b[a]))})},save:function(){var a=this.options.store;a&&a.set(this)},closest:function(a,b){return c(a,b||this.options.draggable,this.el)},option:function(a,b){var c=this.options;return void 0===b?c[a]:(c[a]=b,void("group"===a&&V(c)))},destroy:function(){var a=this.el;a[L]=null,f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),this.nativeDraggable&&(f(a,"dragover",this),f(a,"dragenter",this)),Array.prototype.forEach.call(a.querySelectorAll("[draggable]"),function(a){a.removeAttribute("draggable")}),T.splice(T.indexOf(this._onDragOver),1),this._onDrop(),this.el=a=null}},a.utils={on:e,off:f,css:h,find:i,is:function(a,b){return!!c(a,b,a)},extend:r,throttle:q,closest:c,toggleClass:g,index:p},a.create=function(b,c){return new a(b,c)},a.version="1.3.0-rc1",a}); \ No newline at end of file diff --git a/jquery.binding.js b/jquery.binding.js index 16d7729b4..64b1cf148 100644 --- a/jquery.binding.js +++ b/jquery.binding.js @@ -46,8 +46,11 @@ sortable.destroy(); $el.removeData('sortable'); } - else if (options in sortable) { - retVal = sortable[sortable].apply(sortable, [].slice.call(arguments, 1)); + else if (typeof sortable[options] === 'function') { + retVal = sortable[options].apply(sortable, [].slice.call(arguments, 1)); + } + else if (options in sortable.options) { + retVal = sortable.option.apply(sortable, arguments); } } }); diff --git a/knockout-sortable.js b/knockout-sortable.js index 6a7f70137..224573d36 100644 --- a/knockout-sortable.js +++ b/knockout-sortable.js @@ -1,4 +1,17 @@ -(function () { +(function (factory) { + "use strict"; + if (typeof define === "function" && define.amd) { + // AMD anonymous module + define(["knockout"], factory); + } else if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { + // CommonJS module + var ko = require("knockout"); + factory(ko); + } else { + // No module loader (plain - - - -
          -
        • This is Sortable
        • -
        • It works with Bootstrap...
        • -
        • ...out of the box.
        • -
        • It has support for touch devices.
        • -
        • Just drag some elements around.
        • -
        - - -``` - - ---- - - -### Static methods & properties - - - -##### Sortable.create(el:`HTMLElement`[, options:`Object`]):`Sortable` -Create new instance. - - ---- - - -##### Sortable.active:`Sortable` -Link to the active instance. - - ---- - - -##### Sortable.utils -* on(el`:HTMLElement`, event`:String`, fn`:Function`) — attach an event handler function -* off(el`:HTMLElement`, event`:String`, fn`:Function`) — remove an event handler -* css(el`:HTMLElement`)`:Object` — get the values of all the CSS properties -* css(el`:HTMLElement`, prop`:String`)`:Mixed` — get the value of style properties -* css(el`:HTMLElement`, prop`:String`, value`:String`) — set one CSS properties -* css(el`:HTMLElement`, props`:Object`) — set more CSS properties -* find(ctx`:HTMLElement`, tagName`:String`[, iterator`:Function`])`:Array` — get elements by tag name -* bind(ctx`:Mixed`, fn`:Function`)`:Function` — Takes a function and returns a new one that will always have a particular context -* is(el`:HTMLElement`, selector`:String`)`:Boolean` — check the current matched set of elements against a selector -* closest(el`:HTMLElement`, selector`:String`[, ctx`:HTMLElement`])`:HTMLElement|Null` — for each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree -* toggleClass(el`:HTMLElement`, name`:String`, state`:Boolean`) — add or remove one classes from each element - - ---- - - - -### CDN - -```html - - - - - - - - - - -``` - - ---- - - - -### jQuery compatibility -To assemble plugin for jQuery, perform the following steps: - -```bash - cd Sortable - npm install - grunt jquery -``` - -Now you can use `jquery.fn.sortable.js`:
        -(or `jquery.fn.sortable.min.js` if you run `grunt jquery:min`) - -```js - $("#list").sortable({ /* options */ }); // init - - $("#list").sortable("widget"); // get Sortable instance - - $("#list").sortable("destroy"); // destroy Sortable instance - - $("#list").sortable("{method-name}"); // call an instance method - - $("#list").sortable("{method-name}", "foo", "bar"); // call an instance method with parameters -``` - -And `grunt jquery:mySortableFunc` → `jquery.fn.mySortableFunc.js` - ---- - - -### Contributing (Issue/PR) - -Please, [read this](CONTRIBUTING.md). - - ---- - - -## MIT LICENSE -Copyright 2013-2015 Lebedev Konstantin -http://rubaxa.github.io/Sortable/ - -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. - diff --git a/Sortable.js b/Sortable.js index c9fc59df7..fa1df2c01 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,6 +1,7 @@ /**! * Sortable * @author RubaXa + * @author owenm * @license MIT */ @@ -20,7 +21,7 @@ })(function sortableFactory() { "use strict"; - if (typeof window == "undefined" || !window.document) { + if (typeof window === "undefined" || !window.document) { return function sortableError() { throw new Error("Sortable.js requires a window with a document"); }; @@ -38,63 +39,192 @@ scrollParentEl, scrollCustomFn, - lastEl, - lastCSS, - lastParentCSS, - oldIndex, newIndex, activeGroup, putSortable, - autoScroll = {}, + autoScrolls = [], + scrolling = false, + + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + + pointerElemChangedInterval, + lastPointerElemX, + lastPointerElemY, tapEvt, touchEvt, moved, + + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + lastMode, // 'swap' or 'insert' + + targetMoveDistance, + + + forRepaintDummy, + realDragElRect, // dragEl rect after current animation + /** @const */ R_SPACE = /\s+/g, - R_FLOAT = /left|right|inline/, expando = 'Sortable' + (new Date).getTime(), win = window, document = win.document, parseInt = win.parseInt, + setTimeout = win.setTimeout, $ = win.jQuery || win.Zepto, Polymer = win.Polymer, - captureMode = false, + captureMode = { + capture: false, + passive: false + }, + + IE11OrLess = !!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie|iemobile)/i), + Edge = !!navigator.userAgent.match(/Edge/i), + // FireFox = !!navigator.userAgent.match(/firefox/i), + + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', - supportDraggable = !!('draggable' in document.createElement('div')), - supportCssPointerEvents = (function (el) { - // false when IE11 - if (!!navigator.userAgent.match(/Trident.*rv[ :]?11\./)) { + // This will not pass for IE9, because IE9 DnD only works on anchors + supportDraggable = ('draggable' in document.createElement('div')), + + supportCssPointerEvents = (function() { + // false when <= IE11 + if (IE11OrLess) { return false; } - el = document.createElement('x'); + var el = document.createElement('x'); el.style.cssText = 'pointer-events:auto'; return el.style.pointerEvents === 'auto'; })(), _silent = false, + _alignedSilent = false, abs = Math.abs, min = Math.min, savedInputChecked = [], - touchDragOverListeners = [], - _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) { + _detectDirection = function(el, options) { + var elCSS = _css(el), + elWidth = parseInt(elCSS.width), + child1 = _getChild(el, 0, options), + child2 = _getChild(el, 1, options), + firstChildCSS = child1 && _css(child1), + secondChildCSS = child2 && _css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + _getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + _getRect(child2).width; + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' + ? 'vertical' : 'horizontal'; + } + return (child1 && + ( + firstChildCSS.display === 'block' || + firstChildCSS.display === 'flex' || + firstChildCSS.display === 'table' || + firstChildCSS.display === 'grid' || + firstChildWidth >= elWidth && + elCSS[CSSFloatProperty] === 'none' || + child2 && + elCSS[CSSFloatProperty] === 'none' && + firstChildWidth + secondChildWidth > elWidth + ) ? + 'vertical' : 'horizontal' + ); + }, + + /** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ + _detectNearestEmptySortable = function(x, y) { + for (var i = 0; i < sortables.length; i++) { + if (sortables[i].children.length) continue; + + var rect = _getRect(sortables[i]), + threshold = sortables[i][expando].options.emptyInsertThreshold, + insideHorizontally = x >= (rect.left - threshold) && x <= (rect.right + threshold), + insideVertically = y >= (rect.top - threshold) && y <= (rect.bottom + threshold); + + if (insideHorizontally && insideVertically) { + return sortables[i]; + } + } + }, + + _isClientInRowColumn = function(x, y, el, axis, options) { + var targetRect = _getRect(el), + targetS1Opp = axis === 'vertical' ? targetRect.left : targetRect.top, + targetS2Opp = axis === 'vertical' ? targetRect.right : targetRect.bottom, + mouseOnOppAxis = axis === 'vertical' ? x : y; + + return targetS1Opp < mouseOnOppAxis && mouseOnOppAxis < targetS2Opp; + }, + + _isElInRowColumn = function(el1, el2, axis) { + var el1Rect = el1 === dragEl && realDragElRect || _getRect(el1), + el2Rect = el2 === dragEl && realDragElRect || _getRect(el2), + el1S1Opp = axis === 'vertical' ? el1Rect.left : el1Rect.top, + el1S2Opp = axis === 'vertical' ? el1Rect.right : el1Rect.bottom, + el1OppLength = axis === 'vertical' ? el1Rect.width : el1Rect.height, + el2S1Opp = axis === 'vertical' ? el2Rect.left : el2Rect.top, + el2S2Opp = axis === 'vertical' ? el2Rect.right : el2Rect.bottom, + el2OppLength = axis === 'vertical' ? el2Rect.width : el2Rect.height; + + return ( + el1S1Opp === el2S1Opp || + el1S2Opp === el2S2Opp || + (el1S1Opp + el1OppLength / 2) === (el2S1Opp + el2OppLength / 2) + ); + }, + + _getParentAutoScrollElement = function(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return win; + + var elem = el; + var gotSelf = false; + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = _css(elem); + if ( + elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || + elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll') + ) { + if (!elem || !elem.getBoundingClientRect || elem === document.body) return win; + + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + } while (elem = elem.parentNode); + + return win; + }, + + _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl, /**Boolean*/isFallback) { // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (rootEl && options.scroll) { - var _this = rootEl[expando], - el, - rect, + if (options.scroll) { + var _this = rootEl ? rootEl[expando] : window, sens = options.scrollSensitivity, speed = options.scrollSpeed, @@ -104,98 +234,159 @@ winWidth = window.innerWidth, winHeight = window.innerHeight, - vx, - vy, - - scrollOffsetX, - scrollOffsetY - ; + scrollThisInstance = false; - // Delect scrollEl + // Detect scrollEl if (scrollParentEl !== rootEl) { + _clearAutoScrolls(); + scrollEl = options.scroll; - scrollParentEl = rootEl; scrollCustomFn = options.scrollFn; if (scrollEl === true) { - scrollEl = rootEl; - - do { - if ((scrollEl.offsetWidth < scrollEl.scrollWidth) || - (scrollEl.offsetHeight < scrollEl.scrollHeight) - ) { - break; - } - /* jshint boss:true */ - } while (scrollEl = scrollEl.parentNode); + scrollEl = _getParentAutoScrollElement(rootEl, true); + scrollParentEl = scrollEl; } } - if (scrollEl) { - el = scrollEl; - rect = scrollEl.getBoundingClientRect(); - vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens); - vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens); - } + var layersOut = 0; + var currentParent = scrollEl; + do { + var el = currentParent, + rect = _getRect(el), - if (!(vx || vy)) { - vx = (winWidth - x <= sens) - (x <= sens); - vy = (winHeight - y <= sens) - (y <= sens); + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, - /* jshint expr:true */ - (vx || vy) && (el = win); - } + width = rect.width, + height = rect.height, + scrollWidth, + scrollHeight, - if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) { - autoScroll.el = el; - autoScroll.vx = vx; - autoScroll.vy = vy; + css, - clearInterval(autoScroll.pid); + vx, + vy, - if (el) { - autoScroll.pid = setInterval(function () { - scrollOffsetY = vy ? vy * speed : 0; - scrollOffsetX = vx ? vx * speed : 0; + canScrollX, + canScrollY, - if ('function' === typeof(scrollCustomFn)) { - return scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt); - } + scrollPosX, + scrollPosY; + + + if (el !== win) { + scrollWidth = el.scrollWidth; + scrollHeight = el.scrollHeight; + + css = _css(el); + + canScrollX = width < scrollWidth && (css.overflowX === 'auto' || css.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (css.overflowY === 'auto' || css.overflowY === 'scroll'); + + scrollPosX = el.scrollLeft; + scrollPosY = el.scrollTop; + } else { + scrollWidth = document.documentElement.scrollWidth; + scrollHeight = document.documentElement.scrollHeight; - if (el === win) { - win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); - } else { - el.scrollTop += scrollOffsetY; - el.scrollLeft += scrollOffsetX; + css = _css(document.documentElement); + + canScrollX = width < scrollWidth && (css.overflowX === 'auto' || css.overflowX === 'scroll' || css.overflowX === 'visible'); + canScrollY = height < scrollHeight && (css.overflowY === 'auto' || css.overflowY === 'scroll' || css.overflowY === 'visible'); + + scrollPosX = document.documentElement.scrollLeft; + scrollPosY = document.documentElement.scrollTop; + } + + vx = canScrollX && (abs(right - x) <= sens && (scrollPosX + width) < scrollWidth) - (abs(left - x) <= sens && !!scrollPosX); + + vy = canScrollY && (abs(bottom - y) <= sens && (scrollPosY + height) < scrollHeight) - (abs(top - y) <= sens && !!scrollPosY); + + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; } - }, 24); + } } - } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + + clearInterval(autoScrolls[layersOut].pid); + + if (el && (vx != 0 || vy != 0)) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + autoScrolls[layersOut].pid = setInterval((function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._emulateDragOver(true); + } + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if ('function' === typeof(scrollCustomFn)) { + if (scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + if (autoScrolls[this.layer].el === win) { + win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); + } else { + autoScrolls[this.layer].el.scrollTop += scrollOffsetY; + autoScrolls[this.layer].el.scrollLeft += scrollOffsetX; + } + }).bind({layer: layersOut}), 24); + } + } + layersOut++; + } while (options.bubbleScroll && currentParent !== win && (currentParent = _getParentAutoScrollElement(currentParent, false))); + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not } }, 30), + _clearAutoScrolls = function () { + autoScrolls.forEach(function(autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; + }, + _prepareGroup = function (options) { function toFn(value, pull) { - if (value === void 0 || value === true) { - value = group.name; - } + return function(to, from, dragEl, evt) { + var ret; + var sameGroup = to.options.group.name && + from.options.group.name && + to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt)); + } else { + var otherGroup = (pull ? to : from).options.group.name; - if (typeof value === 'function') { - return value; - } else { - return function (to, from) { - var fromGroup = from.options.group.name; - - return pull - ? value - : value && (value.join - ? value.indexOf(fromGroup) > -1 - : (fromGroup == value) - ); - }; - } + return (value === true || + (typeof value === 'string' && value === otherGroup) || + (value.join && value.indexOf(otherGroup) > -1)); + } + }; } var group = {}; @@ -211,9 +402,77 @@ group.revertClone = originalGroup.revertClone; options.group = group; - } - ; + }, + _checkAlignment = function(evt) { + if (!dragEl || !dragEl.parentNode) return; + dragEl.parentNode[expando] && dragEl.parentNode[expando]._computeIsAligned(evt); + }, + + _isTrueParentSortable = function(el, target) { + var trueParent = target; + while (!trueParent[expando]) { + trueParent = trueParent.parentNode; + } + + return el === trueParent; + }, + + _artificalBubble = function(sortable, originalEvt, method) { + // Artificial IE bubbling + var nextParent = sortable.parentNode; + while (nextParent && !nextParent[expando]) { + nextParent = nextParent.parentNode; + } + + if (nextParent) { + nextParent[expando][method](_extend(originalEvt, { + artificialBubble: true + })); + } + }, + + _hideGhostForTarget = function() { + if (!supportCssPointerEvents && ghostEl) { + _css(ghostEl, 'display', 'none'); + } + }, + + _unhideGhostForTarget = function() { + if (!supportCssPointerEvents && ghostEl) { + _css(ghostEl, 'display', ''); + } + }; + + + // #1184 fix - Prevent click event on fallback if dragged but item not changed position + document.addEventListener('click', function(evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); + + var nearestEmptyInsertDetectEvent = function(evt) { + if (dragEl) { + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + nearest[expando]._onDragOver({ + clientX: evt.clientX, + clientY: evt.clientY, + target: nearest, + rootEl: nearest + }); + } + } + }; + // We do not want this to be triggered if completed (bubbling canceled), so only define it here + document.addEventListener('dragover', nearestEmptyInsertDetectEvent); + document.addEventListener('mousemove', nearestEmptyInsertDetectEvent); /** * @class Sortable @@ -222,7 +481,7 @@ */ function Sortable(el, options) { if (!(el && el.nodeType && el.nodeType === 1)) { - throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); + throw 'Sortable: `el` must be HTMLElement, not ' + {}.toString.call(el); } this.el = el; // root element @@ -234,7 +493,7 @@ // Default options var defaults = { - group: Math.random(), + group: null, sort: true, disabled: false, store: null, @@ -242,7 +501,15 @@ scroll: true, scrollSensitivity: 30, scrollSpeed: 10, + bubbleScroll: true, draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', + swapThreshold: 1, // percentage; 0 <= x <= 1 + invertSwap: false, // invert always + invertedSwapThreshold: null, // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function() { + return _detectDirection(el, this.options); + }, ghostClass: 'sortable-ghost', chosenClass: 'sortable-chosen', dragClass: 'sortable-drag', @@ -250,6 +517,7 @@ filter: null, preventOnFilter: true, animation: 0, + easing: null, setData: function (dataTransfer, dragEl) { dataTransfer.setData('Text', dragEl.textContent); }, @@ -257,11 +525,17 @@ dragoverBubble: false, dataIdAttr: 'data-id', delay: 0, + touchStartThreshold: parseInt(window.devicePixelRatio, 10) || 1, forceFallback: false, fallbackClass: 'sortable-fallback', fallbackOnBody: false, fallbackTolerance: 0, - fallbackOffset: {x: 0, y: 0} + fallbackOffset: {x: 0, y: 0}, + supportPointer: Sortable.supportPointer !== false && ( + ('PointerEvent' in window) || + window.navigator && ('msPointerEnabled' in window.navigator) // microsoft + ), + emptyInsertThreshold: 5 }; @@ -283,26 +557,68 @@ this.nativeDraggable = options.forceFallback ? false : supportDraggable; // Bind events - _on(el, 'mousedown', this._onTapStart); - _on(el, 'touchstart', this._onTapStart); - _on(el, 'pointerdown', this._onTapStart); + if (options.supportPointer) { + _on(el, 'pointerdown', this._onTapStart); + } else { + _on(el, 'mousedown', this._onTapStart); + _on(el, 'touchstart', this._onTapStart); + } if (this.nativeDraggable) { _on(el, 'dragover', this); _on(el, 'dragenter', this); } - touchDragOverListeners.push(this._onDragOver); + sortables.push(this.el); // Restore sorting - options.store && this.sort(options.store.get(this)); + options.store && options.store.get && this.sort(options.store.get(this) || []); } - Sortable.prototype = /** @lends Sortable.prototype */ { constructor: Sortable, + _computeIsAligned: function(evt) { + var target; + + if (ghostEl && !supportCssPointerEvents) { + _hideGhostForTarget(); + target = document.elementFromPoint(evt.clientX, evt.clientY); + _unhideGhostForTarget(); + } else { + target = evt.target; + } + + target = _closest(target, this.options.draggable, this.el, false); + if (_alignedSilent) return; + if (!dragEl || dragEl.parentNode !== this.el) return; + + var children = this.el.children; + for (var i = 0; i < children.length; i++) { + // Don't change for target in case it is changed to aligned before onDragOver is fired + if (_closest(children[i], this.options.draggable, this.el, false) && children[i] !== target) { + children[i].sortableMouseAligned = _isClientInRowColumn(evt.clientX, evt.clientY, children[i], this._getDirection(evt, null), this.options); + } + } + // Used for nulling last target when not in element, nothing to do with checking if aligned + if (!_closest(target, this.options.draggable, this.el, true)) { + lastTarget = null; + } + + _alignedSilent = true; + setTimeout(function() { + _alignedSilent = false; + }, 30); + + }, + + _getDirection: function(evt, target) { + return (typeof this.options.direction === 'function') ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function (/** Event|TouchEvent */evt) { + if (!evt.cancelable) return; + var _this = this, el = this.el, options = this.options, @@ -310,26 +626,39 @@ type = evt.type, touch = evt.touches && evt.touches[0], target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0]) || target, + originalTarget = evt.target.shadowRoot && ((evt.path && evt.path[0]) || (evt.composedPath && evt.composedPath()[0])) || target, filter = options.filter, startIndex; _saveInputCheckedState(el); + // IE: Calls events in capture mode if event element is nested. This ensures only correct element's _onTapStart goes through. + // This process is also done in _onDragOver + if (IE11OrLess && !evt.artificialBubble && !_isTrueParentSortable(el, target)) { + return; + } + // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. if (dragEl) { return; } if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { - return; // only left button or enabled + return; // only left button and enabled } + // cancel dnd if original target is content editable + if (originalTarget.isContentEditable) { + return; + } - target = _closest(target, options.draggable, el); + target = _closest(target, options.draggable, el, false); if (!target) { + if (IE11OrLess) { + _artificalBubble(el, evt, '_onTapStart'); + } return; } @@ -344,28 +673,28 @@ // Check filter if (typeof filter === 'function') { if (filter.call(this, evt, target, this)) { - _dispatchEvent(_this, originalTarget, 'filter', target, el, startIndex); - preventOnFilter && evt.preventDefault(); + _dispatchEvent(_this, originalTarget, 'filter', target, el, el, startIndex); + preventOnFilter && evt.cancelable && evt.preventDefault(); return; // cancel dnd } } else if (filter) { filter = filter.split(',').some(function (criteria) { - criteria = _closest(originalTarget, criteria.trim(), el); + criteria = _closest(originalTarget, criteria.trim(), el, false); if (criteria) { - _dispatchEvent(_this, criteria, 'filter', target, el, startIndex); + _dispatchEvent(_this, criteria, 'filter', target, el, el, startIndex); return true; } }); if (filter) { - preventOnFilter && evt.preventDefault(); + preventOnFilter && evt.cancelable && evt.preventDefault(); return; // cancel dnd } } - if (options.handle && !_closest(originalTarget, options.handle, el)) { + if (options.handle && !_closest(originalTarget, options.handle, el, false)) { return; } @@ -373,6 +702,58 @@ this._prepareDragStart(evt, touch, target, startIndex); }, + + _handleAutoScroll: function(evt, fallback) { + if (!dragEl || !this.options.scroll) return; + var x = evt.clientX, + y = evt.clientY, + + elem = document.elementFromPoint(x, y), + _this = this; + + // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // Firefox and Chrome are good + if (fallback || Edge || IE11OrLess) { + _autoScroll(evt, _this.options, elem, fallback); + + // Listener for pointer element change + var ogElemScroller = _getParentAutoScrollElement(elem, true); + if ( + scrolling && + ( + !pointerElemChangedInterval || + x !== lastPointerElemX || + y !== lastPointerElemY + ) + ) { + + pointerElemChangedInterval && clearInterval(pointerElemChangedInterval); + // Detect for pointer elem change, emulating native DnD behaviour + pointerElemChangedInterval = setInterval(function() { + if (!dragEl) return; + // could also check if scroll direction on newElem changes due to parent autoscrolling + var newElem = _getParentAutoScrollElement(document.elementFromPoint(x, y), true); + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + _clearAutoScrolls(); + _autoScroll(evt, _this.options, ogElemScroller, fallback); + } + }, 10); + lastPointerElemX = x; + lastPointerElemY = y; + } + + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!_this.options.bubbleScroll || _getParentAutoScrollElement(elem, true) === window) { + _clearAutoScrolls(); + return; + } + _autoScroll(evt, _this.options, _getParentAutoScrollElement(elem, false), false); + } + }, + _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) { var _this = this, el = _this.el, @@ -381,8 +762,6 @@ dragStartFn; if (target && !dragEl && (target.parentNode === el)) { - tapEvt = evt; - rootEl = el; dragEl = target; parentEl = dragEl.parentNode; @@ -391,10 +770,19 @@ activeGroup = options.group; oldIndex = startIndex; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + this._lastX = (touch || evt).clientX; this._lastY = (touch || evt).clientY; - dragEl.style['will-change'] = 'transform'; + dragEl.style['will-change'] = 'all'; + // undo animation if needed + dragEl.style.transition = ''; + dragEl.style.transform = ''; dragStartFn = function () { // Delayed drag has been triggered @@ -404,14 +792,14 @@ // Make the element draggable dragEl.draggable = _this.nativeDraggable; - // Chosen item - _toggleClass(dragEl, options.chosenClass, true); - // Bind the events: dragstart/dragend _this._triggerDragStart(evt, touch); // Drag start event - _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, oldIndex); + _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, rootEl, oldIndex); + + // Chosen item + _toggleClass(dragEl, options.chosenClass, true); }; // Disable "draggable" @@ -419,11 +807,14 @@ _find(dragEl, criteria.trim(), _disableDraggable); }); - _on(ownerDocument, 'mouseup', _this._onDrop); - _on(ownerDocument, 'touchend', _this._onDrop); - _on(ownerDocument, 'touchcancel', _this._onDrop); - _on(ownerDocument, 'pointercancel', _this._onDrop); - _on(ownerDocument, 'selectstart', _this); + if (options.supportPointer) { + _on(ownerDocument, 'pointerup', _this._onDrop); + _on(ownerDocument, 'pointercancel', _this._onDrop); + } else { + _on(ownerDocument, 'mouseup', _this._onDrop); + _on(ownerDocument, 'touchend', _this._onDrop); + _on(ownerDocument, 'touchcancel', _this._onDrop); + } if (options.delay) { // If the user moves the pointer or let go the click or touch @@ -432,16 +823,23 @@ _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); _on(ownerDocument, 'touchend', _this._disableDelayedDrag); _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); - _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); - _on(ownerDocument, 'pointermove', _this._disableDelayedDrag); + _on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + _on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && _on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); _this._dragStartTimer = setTimeout(dragStartFn, options.delay); } else { dragStartFn(); } + } + }, - + _delayedDragTouchMoveHandler: function (/** TouchEvent|PointerEvent **/e) { + var touch = e.touches ? e.touches[0] : e; + if (min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) + >= this.options.touchStartThreshold + ) { + this._disableDelayedDrag(); } }, @@ -452,28 +850,25 @@ _off(ownerDocument, 'mouseup', this._disableDelayedDrag); _off(ownerDocument, 'touchend', this._disableDelayedDrag); _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - _off(ownerDocument, 'mousemove', this._disableDelayedDrag); - _off(ownerDocument, 'touchmove', this._disableDelayedDrag); - _off(ownerDocument, 'pointermove', this._disableDelayedDrag); + _off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + _off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + _off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); }, _triggerDragStart: function (/** Event */evt, /** Touch */touch) { touch = touch || (evt.pointerType == 'touch' ? evt : null); - if (touch) { - // Touch device support - tapEvt = { - target: dragEl, - clientX: touch.clientX, - clientY: touch.clientY - }; - - this._onDragStart(tapEvt, 'touch'); - } - else if (!this.nativeDraggable) { - this._onDragStart(tapEvt, true); - } - else { + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + touch && _on(document, 'touchmove', _preventScroll); // must be touchmove to prevent scroll + _on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + _on(document, 'touchmove', _preventScroll); + _on(document, 'touchmove', this._onTouchMove); + } else { + _on(document, 'mousemove', this._onTouchMove); + } + } else { _on(dragEl, 'dragend', this); _on(rootEl, 'dragstart', this._onDragStart); } @@ -481,7 +876,7 @@ try { if (document.selection) { // Timeout neccessary for IE9 - setTimeout(function () { + _nextTick(function () { document.selection.empty(); }); } else { @@ -491,53 +886,66 @@ } }, - _dragStarted: function () { + _dragStarted: function (fallback) { + awaitingDragStarted = false; if (rootEl && dragEl) { + if (this.nativeDraggable) { + _on(document, 'dragover', this._handleAutoScroll); + _on(document, 'dragover', _checkAlignment); + } var options = this.options; // Apply effect + !fallback && _toggleClass(dragEl, options.dragClass, false); _toggleClass(dragEl, options.ghostClass, true); - _toggleClass(dragEl, options.dragClass, false); + + // In case dragging an animated element + _css(dragEl, 'transform', ''); Sortable.active = this; + fallback && this._appendGhost(); + // Drag start event - _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex); + _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, rootEl, oldIndex); } else { this._nulling(); } }, - _emulateDragOver: function () { + _emulateDragOver: function (bypassLastTouchCheck) { if (touchEvt) { - if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { + if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY && !bypassLastTouchCheck) { return; } - this._lastX = touchEvt.clientX; this._lastY = touchEvt.clientY; - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', 'none'); - } + _hideGhostForTarget(); - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY), - parent = target, - i = touchDragOverListeners.length; + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + parent = target; + } if (parent) { do { if (parent[expando]) { - while (i--) { - touchDragOverListeners[i]({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - } + var inserted; - break; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } } target = parent; // store last element @@ -545,56 +953,59 @@ /* jshint boss:true */ while (parent = parent.parentNode); } + dragEl.parentNode[expando]._computeIsAligned(touchEvt); - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', ''); - } + _unhideGhostForTarget(); } }, _onTouchMove: function (/**TouchEvent*/evt) { if (tapEvt) { + if (!evt.cancelable) return; var options = this.options, fallbackTolerance = options.fallbackTolerance, fallbackOffset = options.fallbackOffset, touch = evt.touches ? evt.touches[0] : evt, - dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x, - dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y, + matrix = ghostEl && _matrix(ghostEl), + scaleX = ghostEl && matrix && matrix.a, + scaleY = ghostEl && matrix && matrix.d, + dx = ((touch.clientX - tapEvt.clientX) + fallbackOffset.x) / (scaleX ? scaleX : 1), + dy = ((touch.clientY - tapEvt.clientY) + fallbackOffset.y) / (scaleY ? scaleY : 1), translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; + // only set the status to dragging, when we are actually dragging - if (!Sortable.active) { + if (!Sortable.active && !awaitingDragStarted) { if (fallbackTolerance && min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance ) { return; } - - this._dragStarted(); + this._onDragStart(evt, true); } - // as well as creating the ghost element on the document body - this._appendGhost(); + this._handleAutoScroll(touch, true); + moved = true; touchEvt = touch; + _css(ghostEl, 'webkitTransform', translate3d); _css(ghostEl, 'mozTransform', translate3d); _css(ghostEl, 'msTransform', translate3d); _css(ghostEl, 'transform', translate3d); - evt.preventDefault(); + evt.cancelable && evt.preventDefault(); } }, _appendGhost: function () { if (!ghostEl) { - var rect = dragEl.getBoundingClientRect(), + var rect = _getRect(dragEl, this.options.fallbackOnBody ? document.body : rootEl, true), css = _css(dragEl), - options = this.options, - ghostRect; + options = this.options; ghostEl = dragEl.cloneNode(true); @@ -602,8 +1013,10 @@ _toggleClass(ghostEl, options.fallbackClass, true); _toggleClass(ghostEl, options.dragClass, true); - _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); - _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); + _css(ghostEl, 'box-sizing', 'border-box'); + _css(ghostEl, 'margin', 0); + _css(ghostEl, 'top', rect.top); + _css(ghostEl, 'left', rect.left); _css(ghostEl, 'width', rect.width); _css(ghostEl, 'height', rect.height); _css(ghostEl, 'opacity', '0.8'); @@ -612,65 +1025,68 @@ _css(ghostEl, 'pointerEvents', 'none'); options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); - - // Fixing dimensions. - ghostRect = ghostEl.getBoundingClientRect(); - _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); - _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); } }, - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var dataTransfer = evt.dataTransfer, - options = this.options; - - this._offUpEvents(); + _onDragStart: function (/**Event*/evt, /**boolean*/fallback) { + var _this = this; + var dataTransfer = evt.dataTransfer; + var options = _this.options; - if (activeGroup.checkPull(this, this, dragEl, evt)) { - cloneEl = _clone(dragEl); + // Setup clone + cloneEl = _clone(dragEl); - cloneEl.draggable = false; - cloneEl.style['will-change'] = ''; + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; - _css(cloneEl, 'display', 'none'); - _toggleClass(cloneEl, this.options.chosenClass, false); + this._hideClone(); - rootEl.insertBefore(cloneEl, dragEl); - _dispatchEvent(this, rootEl, 'clone', dragEl); - } + _toggleClass(cloneEl, _this.options.chosenClass, false); - _toggleClass(dragEl, options.dragClass, true); - if (useFallback) { - if (useFallback === 'touch') { - // Bind touch events - _on(document, 'touchmove', this._onTouchMove); - _on(document, 'touchend', this._onDrop); - _on(document, 'touchcancel', this._onDrop); - _on(document, 'pointermove', this._onTouchMove); - _on(document, 'pointerup', this._onDrop); - } else { - // Old brwoser - _on(document, 'mousemove', this._onTouchMove); - _on(document, 'mouseup', this._onDrop); + // #1143: IFrame support workaround + _this._cloneId = _nextTick(function () { + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); } + _dispatchEvent(_this, rootEl, 'clone', dragEl); + }); + + + !fallback && _toggleClass(dragEl, options.dragClass, true); + + // Set proper drop events + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + _off(document, 'mouseup', _this._onDrop); + _off(document, 'touchend', _this._onDrop); + _off(document, 'touchcancel', _this._onDrop); + _off(document, 'pointercancel', _this._onDrop); - this._loopId = setInterval(this._emulateDragOver, 50); - } - else { if (dataTransfer) { dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(this, dataTransfer, dragEl); + options.setData && options.setData.call(_this, dataTransfer, dragEl); } - _on(document, 'drop', this); - setTimeout(this._dragStarted, 0); + _on(document, 'drop', _this); + + // #1276 fix: + _css(dragEl, 'transform', 'translateZ(0)'); } + + awaitingDragStarted = true; + + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback)); + _on(document, 'selectstart', _this); }, + // Returns true - if no further action is needed (either inserted or another condition) _onDragOver: function (/**Event*/evt) { var el = this.el, - target, + target = evt.target, dragRect, targetRect, revert, @@ -678,126 +1094,180 @@ group = options.group, activeSortable = Sortable.active, isOwner = (activeGroup === group), - isMovingBetweenSortable = false, - canSort = options.sort; + canSort = options.sort, + _this = this; - if (evt.preventDefault !== void 0) { - evt.preventDefault(); - !options.dragoverBubble && evt.stopPropagation(); - } + if (_silent) return; - if (dragEl.animated) { + // IE event order fix + if (IE11OrLess && !evt.rootEl && !evt.artificialBubble && !_isTrueParentSortable(el, target)) { return; } + // Return invocation when no further action is needed in another sortable + function completed() { + if (activeSortable) { + // Set ghost class to new sortable's ghost class + _toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + _toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable.active) { + putSortable = _this; + } else if (_this === Sortable.active) { + putSortable = null; + } + + + // Null lastTarget if it is not inside a previously swapped element + if ((target === dragEl && !dragEl.animated) || (target === el && !target.animated)) { + lastTarget = null; + } + // no bubbling and not fallback + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + _this._handleAutoScroll(evt); + dragEl.parentNode[expando]._computeIsAligned(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + + return true; + } + + // Call when dragEl has been inserted + function changed() { + _dispatchEvent(_this, rootEl, 'change', target, el, rootEl, oldIndex, _index(dragEl, options.draggable), evt); + } + + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + moved = true; + target = _closest(target, options.draggable, el, true); + + // target is dragEl or target is animated + if (!!_closest(evt.target, null, dragEl, true) || target.animated) { + return completed(); + } + + if (target !== dragEl) { + ignoreNextClick = false; + } + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list : ( putSortable === this || ( - (activeSortable.lastPullMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && + (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt) ) ) - ) && - (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback + ) ) { - // Smart auto-scrolling - _autoScroll(evt, options, this.el); + var axis = this._getDirection(evt, target); - if (_silent) { - return; - } - - target = _closest(evt.target, options.draggable, el); - dragRect = dragEl.getBoundingClientRect(); - - if (putSortable !== this) { - putSortable = this; - isMovingBetweenSortable = true; - } + dragRect = _getRect(dragEl); if (revert) { - _cloneHide(activeSortable, true); + this._hideClone(); parentEl = rootEl; // actualization - if (cloneEl || nextEl) { - rootEl.insertBefore(dragEl, cloneEl || nextEl); - } - else if (!canSort) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { rootEl.appendChild(dragEl); } - return; + return completed(); } - if ((el.children.length === 0) || (el.children[0] === ghostEl) || - (el === evt.target) && (_ghostIsLast(el, evt)) + _ghostIsLast(evt, axis, el) && !dragEl.animated ) { //assign target only if condition is true if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) { - target = el.lastElementChild; + target = _lastChild(el); } if (target) { - if (target.animated) { - return; - } - - targetRect = target.getBoundingClientRect(); + targetRect = _getRect(target); } - _cloneHide(activeSortable, isOwner); + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(this); + } - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) { - if (!dragEl.contains(el)) { - el.appendChild(dragEl); - parentEl = el; // actualization - } + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + el.appendChild(dragEl); + parentEl = el; // actualization + realDragElRect = null; + changed(); this._animate(dragRect, dragEl); target && this._animate(targetRect, target); + return completed(); } } - else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { - if (lastEl !== target) { - lastEl = target; - lastCSS = _css(target); - lastParentCSS = _css(target.parentNode); + else if (target && target !== dragEl && (target.parentNode[expando] !== void 0) && target !== el) { + var direction = 0, + targetBeforeFirstSwap, + aligned = target.sortableMouseAligned, + differentLevel = dragEl.parentNode !== el, + scrolledPastTop = _isScrolledPast(target, axis === 'vertical' ? 'top' : 'left'); + + if (lastTarget !== target) { + lastMode = null; + targetBeforeFirstSwap = _getRect(target)[axis === 'vertical' ? 'top' : 'left']; + pastFirstInvertThresh = false; } - targetRect = target.getBoundingClientRect(); - - var width = targetRect.right - targetRect.left, - height = targetRect.bottom - targetRect.top, - floating = R_FLOAT.test(lastCSS.cssFloat + lastCSS.display) - || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), - isWide = (target.offsetWidth > dragEl.offsetWidth), - isLong = (target.offsetHeight > dragEl.offsetHeight), - halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, - nextSibling = target.nextElementSibling, - after = false - ; - - if (floating) { - var elTop = dragEl.offsetTop, - tgTop = target.offsetTop; - - if (elTop === tgTop) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; - } - else if (target.previousElementSibling === dragEl || dragEl.previousElementSibling === target) { - after = (evt.clientY - targetRect.top) / height > 0.5; - } else { - after = tgTop > elTop; + // Reference: https://www.lucidchart.com/documents/view/10fa0e93-e362-4126-aca2-b709ee56bd8b/0 + if ( + _isElInRowColumn(dragEl, target, axis) && aligned || + differentLevel || + scrolledPastTop || + options.invertSwap || + lastMode === 'insert' || + // Needed, in the case that we are inside target and inserted because not aligned... aligned will stay false while inside + // and lastMode will change to 'insert', but we must swap + lastMode === 'swap' + ) { + // New target that we will be inside + if (lastMode !== 'swap') { + isCircumstantialInvert = options.invertSwap || differentLevel || scrolling || scrolledPastTop; } - } else if (!isMovingBetweenSortable) { - after = (nextSibling !== dragEl) && !isLong || halfway && isLong; + + direction = _getSwapDirection(evt, target, axis, + options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, + isCircumstantialInvert, + lastTarget === target); + lastMode = 'swap'; + } else { + // Insert at position + direction = _getInsertDirection(target, options); + lastMode = 'insert'; } + if (direction === 0) return completed(); + + realDragElRect = null; + lastTarget = target; + + lastDirection = direction; + + targetRect = _getRect(target); + + var nextSibling = target.nextElementSibling, + after = false; + + after = direction === 1; var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); @@ -809,47 +1279,78 @@ _silent = true; setTimeout(_unsilent, 30); - _cloneHide(activeSortable, isOwner); + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(this); + } - if (!dragEl.contains(el)) { - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); } parentEl = dragEl.parentNode; // actualization + // must be done before animation + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = abs(targetBeforeFirstSwap - _getRect(target)[axis === 'vertical' ? 'top' : 'left']); + } + changed(); + !differentLevel && this._animate(targetRect, target); this._animate(dragRect, dragEl); - this._animate(targetRect, target); + + return completed(); } } + + if (el.contains(dragEl)) { + return completed(); + } + } + + if (IE11OrLess && !evt.rootEl) { + _artificalBubble(el, evt, '_onDragOver'); } + + return false; }, _animate: function (prevRect, target) { var ms = this.options.animation; if (ms) { - var currentRect = target.getBoundingClientRect(); + var currentRect = _getRect(target); - if (prevRect.nodeType === 1) { - prevRect = prevRect.getBoundingClientRect(); + if (target === dragEl) { + realDragElRect = currentRect; } - _css(target, 'transition', 'none'); - _css(target, 'transform', 'translate3d(' - + (prevRect.left - currentRect.left) + 'px,' - + (prevRect.top - currentRect.top) + 'px,0)' - ); - - target.offsetWidth; // repaint + if (prevRect.nodeType === 1) { + prevRect = _getRect(prevRect); + } - _css(target, 'transition', 'all ' + ms + 'ms'); - _css(target, 'transform', 'translate3d(0,0,0)'); + // Check if actually moving position + if ((prevRect.left + prevRect.width / 2) !== (currentRect.left + currentRect.width / 2) + || (prevRect.top + prevRect.height / 2) !== (currentRect.top + currentRect.height / 2) + ) { + var matrix = _matrix(this.el), + scaleX = matrix && matrix.a, + scaleY = matrix && matrix.d; + + _css(target, 'transition', 'none'); + _css(target, 'transform', 'translate3d(' + + (prevRect.left - currentRect.left) / (scaleX ? scaleX : 1) + 'px,' + + (prevRect.top - currentRect.top) / (scaleY ? scaleY : 1) + 'px,0)' + ); + + forRepaintDummy = target.offsetWidth; // repaint + _css(target, 'transition', 'transform ' + ms + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + _css(target, 'transform', 'translate3d(0,0,0)'); + } - clearTimeout(target.animated); + (typeof target.animated === 'number') && clearTimeout(target.animated); target.animated = setTimeout(function () { _css(target, 'transition', ''); _css(target, 'transform', ''); @@ -861,6 +1362,8 @@ _offUpEvents: function () { var ownerDocument = this.el.ownerDocument; + _off(document, 'touchmove', _preventScroll); + _off(document, 'pointermove', _preventScroll); _off(document, 'touchmove', this._onTouchMove); _off(document, 'pointermove', this._onTouchMove); _off(ownerDocument, 'mouseup', this._onDrop); @@ -868,36 +1371,51 @@ _off(ownerDocument, 'pointerup', this._onDrop); _off(ownerDocument, 'touchcancel', this._onDrop); _off(ownerDocument, 'pointercancel', this._onDrop); - _off(ownerDocument, 'selectstart', this); + _off(document, 'selectstart', this); }, _onDrop: function (/**Event*/evt) { var el = this.el, options = this.options; + awaitingDragStarted = false; + scrolling = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); - clearInterval(autoScroll.pid); + + clearInterval(pointerElemChangedInterval); + _clearAutoScrolls(); + _cancelThrottle(); + clearTimeout(this._dragStartTimer); + _cancelNextTick(this._cloneId); + _cancelNextTick(this._dragStartId); + // Unbind events _off(document, 'mousemove', this._onTouchMove); + if (this.nativeDraggable) { _off(document, 'drop', this); _off(el, 'dragstart', this._onDragStart); + _off(document, 'dragover', this._handleAutoScroll); + _off(document, 'dragover', _checkAlignment); } this._offUpEvents(); if (evt) { if (moved) { - evt.preventDefault(); + evt.cancelable && evt.preventDefault(); !options.dropBubble && evt.stopPropagation(); } ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - if (rootEl === parentEl || Sortable.active.lastPullMode !== 'clone') { + if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) { // Remove clone cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); } @@ -911,26 +1429,28 @@ dragEl.style['will-change'] = ''; // Remove class's - _toggleClass(dragEl, this.options.ghostClass, false); + _toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); _toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event - _dispatchEvent(this, rootEl, 'unchoose', dragEl, rootEl, oldIndex); + _dispatchEvent(this, rootEl, 'unchoose', dragEl, parentEl, rootEl, oldIndex, null, evt); if (rootEl !== parentEl) { newIndex = _index(dragEl, options.draggable); if (newIndex >= 0) { // Add event - _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(null, parentEl, 'add', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'remove', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); // drag from one list and drop into another - _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(null, parentEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); } + + putSortable && putSortable.save(); } else { if (dragEl.nextSibling !== nextEl) { @@ -939,8 +1459,8 @@ if (newIndex >= 0) { // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'update', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); } } } @@ -951,7 +1471,7 @@ newIndex = oldIndex; } - _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'end', dragEl, parentEl, rootEl, oldIndex, newIndex, evt); // Save sorting this.save(); @@ -959,7 +1479,6 @@ } } - this._nulling(); }, @@ -974,15 +1493,24 @@ scrollEl = scrollParentEl = + autoScrolls.length = + + pointerElemChangedInterval = + lastPointerElemX = + lastPointerElemY = tapEvt = touchEvt = moved = newIndex = + oldIndex = + + lastTarget = + lastDirection = - lastEl = - lastCSS = + forRepaintDummy = + realDragElRect = putSortable = activeGroup = @@ -991,6 +1519,7 @@ savedInputChecked.forEach(function (el) { el.checked = true; }); + savedInputChecked.length = 0; }, @@ -1001,8 +1530,8 @@ this._onDrop(evt); break; - case 'dragover': case 'dragenter': + case 'dragover': if (dragEl) { this._onDragOver(evt); _globalDragOver(evt); @@ -1030,7 +1559,7 @@ for (; i < n; i++) { el = children[i]; - if (_closest(el, options.draggable, this.el)) { + if (_closest(el, options.draggable, this.el, false)) { order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); } } @@ -1049,7 +1578,7 @@ this.toArray().forEach(function (id, i) { var el = rootEl.children[i]; - if (_closest(el, this.options.draggable, rootEl)) { + if (_closest(el, this.options.draggable, rootEl, false)) { items[id] = el; } }, this); @@ -1068,7 +1597,7 @@ */ save: function () { var store = this.options.store; - store && store.set(this); + store && store.set && store.set(this); }, @@ -1079,7 +1608,7 @@ * @returns {HTMLElement|null} */ closest: function (el, selector) { - return _closest(el, selector || this.options.draggable, this.el); + return _closest(el, selector || this.options.draggable, this.el, false); }, @@ -1120,53 +1649,63 @@ _off(el, 'dragover', this); _off(el, 'dragenter', this); } - // Remove draggable attributes Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { el.removeAttribute('draggable'); }); - touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); - this._onDrop(); + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; - } - }; + }, + _hideClone: function() { + if (!cloneEl.cloneHidden) { + _css(cloneEl, 'display', 'none'); + cloneEl.cloneHidden = true; + if (cloneEl.parentNode && this.options.removeCloneOnHide) { + cloneEl.parentNode.removeChild(cloneEl); + } + } + }, - function _cloneHide(sortable, state) { - if (sortable.lastPullMode !== 'clone') { - state = true; - } + _showClone: function(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + return; + } - if (cloneEl && (cloneEl.state !== state)) { - _css(cloneEl, 'display', state ? 'none' : ''); + if (cloneEl.cloneHidden) { + // show clone at dragEl or original position + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } - if (!state) { - if (cloneEl.state) { - if (sortable.options.group.revertClone) { - rootEl.insertBefore(cloneEl, nextEl); - sortable._animate(dragEl, cloneEl); - } else { - rootEl.insertBefore(cloneEl, dragEl); - } + if (this.options.group.revertClone) { + this._animate(dragEl, cloneEl); } + _css(cloneEl, 'display', ''); + cloneEl.cloneHidden = false; } - - cloneEl.state = state; } - } - + }; - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { + function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { if (el) { ctx = ctx || document; do { - if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector)) { + if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector) || (includeCTX && el === ctx)) { return el; } + + if (el === ctx) break; /* jshint boss:true */ } while (el = _getParentOrHost(el)); } @@ -1176,9 +1715,9 @@ function _getParentOrHost(el) { - var parent = el.host; - - return (parent && parent.nodeType) ? parent : el.parentNode; + return (el.host && el !== document && el.host.nodeType) + ? el.host + : el.parentNode; } @@ -1186,7 +1725,7 @@ if (evt.dataTransfer) { evt.dataTransfer.dropEffect = 'move'; } - evt.preventDefault(); + evt.cancelable && evt.preventDefault(); } @@ -1201,7 +1740,7 @@ function _toggleClass(el, name, state) { - if (el) { + if (el && name) { if (el.classList) { el.classList[state ? 'add' : 'remove'](name); } @@ -1228,7 +1767,7 @@ return prop === void 0 ? val : val[prop]; } else { - if (!(prop in style)) { + if (!(prop in style) && prop.indexOf('webkit') === -1) { prop = '-webkit-' + prop; } @@ -1237,6 +1776,26 @@ } } + function _matrix(el) { + var appliedTransforms = ''; + do { + var transform = _css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + } while (el = el.parentNode); + + if (window.DOMMatrix) { + return new DOMMatrix(appliedTransforms); + } else if (window.WebKitCSSMatrix) { + return new WebKitCSSMatrix(appliedTransforms); + } else if (window.CSSMatrix) { + return new CSSMatrix(appliedTransforms); + } + } + function _find(ctx, tagName, iterator) { if (ctx) { @@ -1256,16 +1815,23 @@ - function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) { + function _dispatchEvent(sortable, rootEl, name, targetEl, toEl, fromEl, startIndex, newIndex, originalEvt) { sortable = (sortable || rootEl[expando]); - - var evt = document.createEvent('Event'), + var evt, options = sortable.options, onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + // Support for new CustomEvent feature + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } - evt.initEvent(name, true, true); - - evt.to = rootEl; + evt.to = toEl || rootEl; evt.from = fromEl || rootEl; evt.item = targetEl || rootEl; evt.clone = cloneEl; @@ -1273,7 +1839,11 @@ evt.oldIndex = startIndex; evt.newIndex = newIndex; - rootEl.dispatchEvent(evt); + evt.originalEvent = originalEvt; + + if (rootEl) { + rootEl.dispatchEvent(evt); + } if (options[onName]) { options[onName].call(sortable, evt); @@ -1286,18 +1856,27 @@ sortable = fromEl[expando], onMoveFn = sortable.options.onMove, retVal; - - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); + // Support for new CustomEvent feature + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } evt.to = toEl; evt.from = fromEl; evt.dragged = dragEl; evt.draggedRect = dragRect; evt.related = targetEl || toEl; - evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + evt.relatedRect = targetRect || _getRect(toEl); evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvt; + fromEl.dispatchEvent(evt); if (onMoveFn) { @@ -1307,26 +1886,166 @@ return retVal; } - function _disableDraggable(el) { el.draggable = false; } - function _unsilent() { _silent = false; } + /** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + function _getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if ( + children[i].style.display !== 'none' && + children[i] !== ghostEl && + children[i] !== dragEl && + _closest(children[i], options.draggable, el, false) + ) { + if (currentChild === childNum) { + return children[i]; + } + currentChild++; + } + + i++; + } + return null; + } + + /** + * Gets the last child in the el, ignoring ghostEl + * @param {HTMLElement} el Parent element + * @return {HTMLElement} The last child, ignoring ghostEl + */ + function _lastChild(el) { + var last = el.lastElementChild; + + if (last === ghostEl) { + last = el.children[el.childElementCount - 2]; + } - /** @returns {HTMLElement|false} */ - function _ghostIsLast(el, evt) { - var lastEl = el.lastElementChild, - rect = lastEl.getBoundingClientRect(); + return last || null; + } - // 5 — min delta - // abs — нельзя добавлять, а то глюки при наведении сверху - return (evt.clientY - (rect.top + rect.height) > 5) || - (evt.clientX - (rect.left + rect.width) > 5); + function _ghostIsLast(evt, axis, el) { + var elRect = _getRect(_lastChild(el)), + mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, + mouseOnOppAxis = axis === 'vertical' ? evt.clientX : evt.clientY, + targetS2 = axis === 'vertical' ? elRect.bottom : elRect.right, + targetS1Opp = axis === 'vertical' ? elRect.left : elRect.top, + targetS2Opp = axis === 'vertical' ? elRect.right : elRect.bottom; + + return ( + mouseOnOppAxis > targetS1Opp && + mouseOnOppAxis < targetS2Opp && + mouseOnAxis > targetS2 + ); + } + + function _getSwapDirection(evt, target, axis, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var targetRect = _getRect(target), + mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, + targetLength = axis === 'vertical' ? targetRect.height : targetRect.width, + targetS1 = axis === 'vertical' ? targetRect.top : targetRect.left, + targetS2 = axis === 'vertical' ? targetRect.bottom : targetRect.right, + dragRect = _getRect(dragEl), + invert = false; + + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && + (lastDirection === 1 ? + ( + mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 + ) : + ( + mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2 + ) + ) + ) + { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + var dragS1 = axis === 'vertical' ? dragRect.top : dragRect.left, + dragS2 = axis === 'vertical' ? dragRect.bottom : dragRect.right; + // dragEl shadow (target move distance shadow) + if ( + lastDirection === 1 ? + ( + mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + ) : + ( + mouseOnAxis > targetS2 - targetMoveDistance + ) + ) + { + return lastDirection * -1; + } + } else { + invert = true; + } + } else { + // Regular + if ( + mouseOnAxis > targetS1 + (targetLength * (1 - swapThreshold) / 2) && + mouseOnAxis < targetS2 - (targetLength * (1 - swapThreshold) / 2) + ) { + return ((mouseOnAxis > targetS1 + targetLength / 2) ? -1 : 1); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if ( + mouseOnAxis < targetS1 + (targetLength * invertedSwapThreshold / 2) || + mouseOnAxis > targetS2 - (targetLength * invertedSwapThreshold / 2) + ) + { + return ((mouseOnAxis > targetS1 + targetLength / 2) ? 1 : -1); + } + } + + return 0; + } + + /** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @param {Object} options options of the parent sortable + * @return {Number} Direction dragEl must be swapped + */ + function _getInsertDirection(target, options) { + var dragElIndex = _index(dragEl, options.draggable), + targetIndex = _index(target, options.draggable); + + if (dragElIndex < targetIndex) { + return 1; + } else { + return -1; + } } @@ -1363,7 +2082,7 @@ } while (el && (el = el.previousElementSibling)) { - if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) { + if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && el !== cloneEl) { index++; } } @@ -1373,41 +2092,47 @@ function _matches(/**HTMLElement*/el, /**String*/selector) { if (el) { - selector = selector.split('.'); - - var tag = selector.shift().toUpperCase(), - re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g'); - - return ( - (tag === '' || el.nodeName.toUpperCase() == tag) && - (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length) - ); + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch(_) { + return false; + } } return false; } + var _throttleTimeout; function _throttle(callback, ms) { - var args, _this; - return function () { - if (args === void 0) { - args = arguments; - _this = this; + if (!_throttleTimeout) { + var args = arguments, + _this = this; - setTimeout(function () { + _throttleTimeout = setTimeout(function () { if (args.length === 1) { callback.call(_this, args[0]); } else { callback.apply(_this, args); } - args = void 0; + _throttleTimeout = void 0; }, ms); } }; } + function _cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; + } + function _extend(dst, src) { if (dst && src) { for (var key in src) { @@ -1421,15 +2146,20 @@ } function _clone(el) { - return $ - ? $(el).clone(true)[0] - : (Polymer && Polymer.dom - ? Polymer.dom(el).cloneNode(true) - : el.cloneNode(true) - ); + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } + else if ($) { + return $(el).clone(true)[0]; + } + else { + return el.cloneNode(true); + } } function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); var idx = inputs.length; @@ -1439,23 +2169,139 @@ } } - // Fixed #973: - _on(document, 'touchmove', function (evt) { - if (Sortable.active) { + function _nextTick(fn) { + return setTimeout(fn, 0); + } + + function _cancelNextTick(id) { + return clearTimeout(id); + } + + + function _preventScroll(evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { evt.preventDefault(); } - }); - - try { - window.addEventListener('test', null, Object.defineProperty({}, 'passive', { - get: function () { - captureMode = { - capture: false, - passive: false - }; + } + + /** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[HTMLElement]} container the parent the element will be placed in + * @param {[Boolean]} adjustForTransform Whether the rect should compensate for parent's transform + * (used for fixed positioning on el) + * @return {Object} The boundingClientRect of el + */ + function _getRect(el, container, adjustForTransform) { + if (!el.getBoundingClientRect && el !== win) return; + + var elRect, + top, + left, + bottom, + right, + height, + width; + + if (el !== win) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if (adjustForTransform && el !== win) { + // Adjust for translate() + container = container || el.parentNode; + + // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && _css(container, 'transform') !== 'none') { + var containerRect = container.getBoundingClientRect(); + + // Set relative to edges of padding box of container + top -= containerRect.top + parseInt(_css(container, 'border-top-width')); + left -= containerRect.left + parseInt(_css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + + break; + } + /* jshint boss:true */ + } while (container = container.parentNode); + } + + // Adjust for scale() + var matrix = _matrix(el), + scaleX = matrix && matrix.a, + scaleY = matrix && matrix.d; + + if (matrix) { + top /= scaleY; + left /= scaleX; + + width /= scaleX; + height /= scaleY; + + bottom = top + height; + right = left + width; } - })); - } catch (err) {} + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; + } + + + /** + * Checks if a side of an element is scrolled past a side of it's parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {String} side Side of the element in question ('top', 'left', 'right', 'bottom') + * @return {Boolean} Whether the element is overflowing the viewport on the given side of it's parent + */ + function _isScrolledPast(el, side) { + var parent = _getParentAutoScrollElement(parent, true), + elSide = _getRect(el)[side]; + + /* jshint boss:true */ + while (parent) { + var parentSide = _getRect(parent)[side], + visible; + + if (side === 'top' || side === 'left') { + visible = elSide >= parentSide; + } else { + visible = elSide <= parentSide; + } + + if (!visible) return true; + + if (parent === win) break; + + parent = _getParentAutoScrollElement(parent, false); + } + + return false; + } + // Export utils Sortable.utils = { @@ -1464,14 +2310,18 @@ css: _css, find: _find, is: function (el, selector) { - return !!_closest(el, selector, el); + return !!_closest(el, selector, el, false); }, extend: _extend, throttle: _throttle, closest: _closest, toggleClass: _toggleClass, clone: _clone, - index: _index + index: _index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: _getChild }; @@ -1486,6 +2336,6 @@ // Export - Sortable.version = '1.6.1'; + Sortable.version = '1.8.0'; return Sortable; }); diff --git a/Sortable.min.js b/Sortable.min.js index 6b846ce25..40af53c24 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,3 @@ -/*! Sortable 1.6.1 - MIT | git://github.com/rubaxa/Sortable.git */ -!function(a){"use strict";"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=a():window.Sortable=a()}(function(){"use strict";function a(a,b){if(!a||!a.nodeType||1!==a.nodeType)throw"Sortable: `el` must be HTMLElement, and not "+{}.toString.call(a);this.el=a,this.options=b=t({},b),a[T]=this;var c={group:Math.random(),sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,draggable:/[uo]l/i.test(a.nodeName)?"li":">*",ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,setData:function(a,b){a.setData("Text",b.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0}};for(var d in c)!(d in b)&&(b[d]=c[d]);ga(b);for(var e in this)"_"===e.charAt(0)&&"function"==typeof this[e]&&(this[e]=this[e].bind(this));this.nativeDraggable=!b.forceFallback&&$,f(a,"mousedown",this._onTapStart),f(a,"touchstart",this._onTapStart),f(a,"pointerdown",this._onTapStart),this.nativeDraggable&&(f(a,"dragover",this),f(a,"dragenter",this)),ea.push(this._onDragOver),b.store&&this.sort(b.store.get(this))}function b(a,b){"clone"!==a.lastPullMode&&(b=!0),z&&z.state!==b&&(i(z,"display",b?"none":""),b||z.state&&(a.options.group.revertClone?(A.insertBefore(z,B),a._animate(w,z)):A.insertBefore(z,w)),z.state=b)}function c(a,b,c){if(a){c=c||V;do if(">*"===b&&a.parentNode===c||r(a,b))return a;while(a=d(a))}return null}function d(a){var b=a.host;return b&&b.nodeType?b:a.parentNode}function e(a){a.dataTransfer&&(a.dataTransfer.dropEffect="move"),a.preventDefault()}function f(a,b,c){a.addEventListener(b,c,Z)}function g(a,b,c){a.removeEventListener(b,c,Z)}function h(a,b,c){if(a)if(a.classList)a.classList[c?"add":"remove"](b);else{var d=(" "+a.className+" ").replace(R," ").replace(" "+b+" "," ");a.className=(d+(c?" "+b:"")).replace(R," ")}}function i(a,b,c){var d=a&&a.style;if(d){if(void 0===c)return V.defaultView&&V.defaultView.getComputedStyle?c=V.defaultView.getComputedStyle(a,""):a.currentStyle&&(c=a.currentStyle),void 0===b?c:c[b];b in d||(b="-webkit-"+b),d[b]=c+("string"==typeof c?"":"px")}}function j(a,b,c){if(a){var d=a.getElementsByTagName(b),e=0,f=d.length;if(c)for(;e5||b.clientX-(d.left+d.width)>5}function p(a){for(var b=a.tagName+a.className+a.src+a.href+a.textContent,c=b.length,d=0;c--;)d+=b.charCodeAt(c);return d.toString(36)}function q(a,b){var c=0;if(!a||!a.parentNode)return-1;for(;a&&(a=a.previousElementSibling);)"TEMPLATE"===a.nodeName.toUpperCase()||">*"!==b&&!r(a,b)||c++;return c}function r(a,b){if(a){b=b.split(".");var c=b.shift().toUpperCase(),d=new RegExp("\\s("+b.join("|")+")(?=\\s)","g");return!(""!==c&&a.nodeName.toUpperCase()!=c||b.length&&((" "+a.className+" ").match(d)||[]).length!=b.length)}return!1}function s(a,b){var c,d;return function(){void 0===c&&(c=arguments,d=this,setTimeout(function(){1===c.length?a.call(d,c[0]):a.apply(d,c),c=void 0},b))}}function t(a,b){if(a&&b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function u(a){return X?X(a).clone(!0)[0]:Y&&Y.dom?Y.dom(a).cloneNode(!0):a.cloneNode(!0)}function v(a){for(var b=a.getElementsByTagName("input"),c=b.length;c--;){var d=b[c];d.checked&&da.push(d)}}if("undefined"==typeof window||!window.document)return function(){throw new Error("Sortable.js requires a window with a document")};var w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q={},R=/\s+/g,S=/left|right|inline/,T="Sortable"+(new Date).getTime(),U=window,V=U.document,W=U.parseInt,X=U.jQuery||U.Zepto,Y=U.Polymer,Z=!1,$=!!("draggable"in V.createElement("div")),_=function(a){return!navigator.userAgent.match(/Trident.*rv[ :]?11\./)&&(a=V.createElement("x"),a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents)}(),aa=!1,ba=Math.abs,ca=Math.min,da=[],ea=[],fa=s(function(a,b,c){if(c&&b.scroll){var d,e,f,g,h,i,j=c[T],k=b.scrollSensitivity,l=b.scrollSpeed,m=a.clientX,n=a.clientY,o=window.innerWidth,p=window.innerHeight;if(E!==c&&(D=b.scroll,E=c,F=b.scrollFn,D===!0)){D=c;do if(D.offsetWidth-1:e==a)}}var c={},d=a.group;d&&"object"==typeof d||(d={name:d}),c.name=d.name,c.checkPull=b(d.pull,!0),c.checkPut=b(d.put),c.revertClone=d.revertClone,a.group=c};a.prototype={constructor:a,_onTapStart:function(a){var b,d=this,e=this.el,f=this.options,g=f.preventOnFilter,h=a.type,i=a.touches&&a.touches[0],j=(i||a).target,l=a.target.shadowRoot&&a.path&&a.path[0]||j,m=f.filter;if(v(e),!w&&!(/mousedown|pointerdown/.test(h)&&0!==a.button||f.disabled)&&(j=c(j,f.draggable,e),j&&C!==j)){if(b=q(j,f.draggable),"function"==typeof m){if(m.call(this,a,j,this))return k(d,l,"filter",j,e,b),void(g&&a.preventDefault())}else if(m&&(m=m.split(",").some(function(a){if(a=c(l,a.trim(),e))return k(d,a,"filter",j,e,b),!0})))return void(g&&a.preventDefault());f.handle&&!c(l,f.handle,e)||this._prepareDragStart(a,i,j,b)}},_prepareDragStart:function(a,b,c,d){var e,g=this,i=g.el,l=g.options,n=i.ownerDocument;c&&!w&&c.parentNode===i&&(N=a,A=i,w=c,x=w.parentNode,B=w.nextSibling,C=c,L=l.group,J=d,this._lastX=(b||a).clientX,this._lastY=(b||a).clientY,w.style["will-change"]="transform",e=function(){g._disableDelayedDrag(),w.draggable=g.nativeDraggable,h(w,l.chosenClass,!0),g._triggerDragStart(a,b),k(g,A,"choose",w,A,J)},l.ignore.split(",").forEach(function(a){j(w,a.trim(),m)}),f(n,"mouseup",g._onDrop),f(n,"touchend",g._onDrop),f(n,"touchcancel",g._onDrop),f(n,"pointercancel",g._onDrop),f(n,"selectstart",g),l.delay?(f(n,"mouseup",g._disableDelayedDrag),f(n,"touchend",g._disableDelayedDrag),f(n,"touchcancel",g._disableDelayedDrag),f(n,"mousemove",g._disableDelayedDrag),f(n,"touchmove",g._disableDelayedDrag),f(n,"pointermove",g._disableDelayedDrag),g._dragStartTimer=setTimeout(e,l.delay)):e())},_disableDelayedDrag:function(){var a=this.el.ownerDocument;clearTimeout(this._dragStartTimer),g(a,"mouseup",this._disableDelayedDrag),g(a,"touchend",this._disableDelayedDrag),g(a,"touchcancel",this._disableDelayedDrag),g(a,"mousemove",this._disableDelayedDrag),g(a,"touchmove",this._disableDelayedDrag),g(a,"pointermove",this._disableDelayedDrag)},_triggerDragStart:function(a,b){b=b||("touch"==a.pointerType?a:null),b?(N={target:w,clientX:b.clientX,clientY:b.clientY},this._onDragStart(N,"touch")):this.nativeDraggable?(f(w,"dragend",this),f(A,"dragstart",this._onDragStart)):this._onDragStart(N,!0);try{V.selection?setTimeout(function(){V.selection.empty()}):window.getSelection().removeAllRanges()}catch(a){}},_dragStarted:function(){if(A&&w){var b=this.options;h(w,b.ghostClass,!0),h(w,b.dragClass,!1),a.active=this,k(this,A,"start",w,A,J)}else this._nulling()},_emulateDragOver:function(){if(O){if(this._lastX===O.clientX&&this._lastY===O.clientY)return;this._lastX=O.clientX,this._lastY=O.clientY,_||i(y,"display","none");var a=V.elementFromPoint(O.clientX,O.clientY),b=a,c=ea.length;if(b)do{if(b[T]){for(;c--;)ea[c]({clientX:O.clientX,clientY:O.clientY,target:a,rootEl:b});break}a=b}while(b=b.parentNode);_||i(y,"display","")}},_onTouchMove:function(b){if(N){var c=this.options,d=c.fallbackTolerance,e=c.fallbackOffset,f=b.touches?b.touches[0]:b,g=f.clientX-N.clientX+e.x,h=f.clientY-N.clientY+e.y,j=b.touches?"translate3d("+g+"px,"+h+"px,0)":"translate("+g+"px,"+h+"px)";if(!a.active){if(d&&ca(ba(f.clientX-this._lastX),ba(f.clientY-this._lastY))w.offsetWidth,D=e.offsetHeight>w.offsetHeight,E=(v?(d.clientX-g.left)/t:(d.clientY-g.top)/u)>.5,F=e.nextElementSibling,J=!1;if(v){var K=w.offsetTop,N=e.offsetTop;J=K===N?e.previousElementSibling===w&&!C||E&&C:e.previousElementSibling===w||w.previousElementSibling===e?(d.clientY-g.top)/u>.5:N>K}else r||(J=F!==w&&!D||E&&D);var O=l(A,j,w,f,e,g,d,J);O!==!1&&(1!==O&&O!==-1||(J=1===O),aa=!0,setTimeout(n,30),b(p,q),w.contains(j)||(J&&!F?j.appendChild(w):e.parentNode.insertBefore(w,J?F:e)),x=w.parentNode,this._animate(f,w),this._animate(g,e))}}},_animate:function(a,b){var c=this.options.animation;if(c){var d=b.getBoundingClientRect();1===a.nodeType&&(a=a.getBoundingClientRect()),i(b,"transition","none"),i(b,"transform","translate3d("+(a.left-d.left)+"px,"+(a.top-d.top)+"px,0)"),b.offsetWidth,i(b,"transition","all "+c+"ms"),i(b,"transform","translate3d(0,0,0)"),clearTimeout(b.animated),b.animated=setTimeout(function(){i(b,"transition",""),i(b,"transform",""),b.animated=!1},c)}},_offUpEvents:function(){var a=this.el.ownerDocument;g(V,"touchmove",this._onTouchMove),g(V,"pointermove",this._onTouchMove),g(a,"mouseup",this._onDrop),g(a,"touchend",this._onDrop),g(a,"pointerup",this._onDrop),g(a,"touchcancel",this._onDrop),g(a,"pointercancel",this._onDrop),g(a,"selectstart",this)},_onDrop:function(b){var c=this.el,d=this.options;clearInterval(this._loopId),clearInterval(Q.pid),clearTimeout(this._dragStartTimer),g(V,"mousemove",this._onTouchMove),this.nativeDraggable&&(g(V,"drop",this),g(c,"dragstart",this._onDragStart)),this._offUpEvents(),b&&(P&&(b.preventDefault(),!d.dropBubble&&b.stopPropagation()),y&&y.parentNode&&y.parentNode.removeChild(y),A!==x&&"clone"===a.active.lastPullMode||z&&z.parentNode&&z.parentNode.removeChild(z),w&&(this.nativeDraggable&&g(w,"dragend",this),m(w),w.style["will-change"]="",h(w,this.options.ghostClass,!1),h(w,this.options.chosenClass,!1),k(this,A,"unchoose",w,A,J),A!==x?(K=q(w,d.draggable),K>=0&&(k(null,x,"add",w,A,J,K),k(this,A,"remove",w,A,J,K),k(null,x,"sort",w,A,J,K),k(this,A,"sort",w,A,J,K))):w.nextSibling!==B&&(K=q(w,d.draggable),K>=0&&(k(this,A,"update",w,A,J,K),k(this,A,"sort",w,A,J,K))),a.active&&(null!=K&&K!==-1||(K=J),k(this,A,"end",w,A,J,K),this.save()))),this._nulling()},_nulling:function(){A=w=x=y=B=z=C=D=E=N=O=P=K=G=H=M=L=a.active=null,da.forEach(function(a){a.checked=!0}),da.length=0},handleEvent:function(a){switch(a.type){case"drop":case"dragend":this._onDrop(a);break;case"dragover":case"dragenter":w&&(this._onDragOver(a),e(a));break;case"selectstart":a.preventDefault()}},toArray:function(){for(var a,b=[],d=this.el.children,e=0,f=d.length,g=this.options;e=o.left-i&&t<=o.right+i,a=e>=o.top-i&&e<=o.bottom+i;if(r&&a)return d[n]}}(t.clientX,t.clientY);e&&e[dt]._onDragOver({clientX:t.clientX,clientY:t.clientY,target:e,rootEl:e})}};function _t(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be HTMLElement, not "+{}.toString.call(t);this.el=t,this.options=e=U({},e),t[dt]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0,draggable:/[uo]l/i.test(t.nodeName)?"li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return D(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,touchStartThreshold:g(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==_t.supportPointer&&("PointerEvent"in window||window.navigator&&"msPointerEnabled"in window.navigator),emptyInsertThreshold:5};for(var o in n)!(o in e)&&(e[o]=n[o]);for(var i in S(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&a,e.supportPointer?M(t,"pointerdown",this._onTapStart):(M(t,"mousedown",this._onTapStart),M(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(M(t,"dragover",this),M(t,"dragenter",this)),d.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[])}function yt(t,e,n,o){if(t){n=n||ut;do{if(">*"===e&&t.parentNode===n||z(t,e)||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==ut&&i.host.nodeType?i.host:i.parentNode)}var i;return null}function M(t,e,n){t.addEventListener(e,n,r)}function O(t,e,n){t.removeEventListener(e,n,r)}function Dt(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(i," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(i," ")}}function B(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return ut.defaultView&&ut.defaultView.getComputedStyle?n=ut.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function H(t){var e="";do{var n=B(t,"transform");n&&"none"!==n&&(e=n+" "+e)}while(t=t.parentNode);return window.DOMMatrix?new DOMMatrix(e):window.WebKitCSSMatrix?new WebKitCSSMatrix(e):window.CSSMatrix?new CSSMatrix(e):void 0}function R(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=this.options.touchStartThreshold&&this._disableDelayedDrag()},_disableDelayedDrag:function(){var t=this.el.ownerDocument;clearTimeout(this._dragStartTimer),O(t,"mouseup",this._disableDelayedDrag),O(t,"touchend",this._disableDelayedDrag),O(t,"touchcancel",this._disableDelayedDrag),O(t,"mousemove",this._delayedDragTouchMoveHandler),O(t,"touchmove",this._delayedDragTouchMoveHandler),O(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||("touch"==t.pointerType?t:null),!this.nativeDraggable||e?this.options.supportPointer?(e&&M(ut,"touchmove",Yt),M(ut,"pointermove",this._onTouchMove)):e?(M(ut,"touchmove",Yt),M(ut,"touchmove",this._onTouchMove)):M(ut,"mousemove",this._onTouchMove):(M(V,"dragend",this),M(K,"dragstart",this._onDragStart));try{ut.selection?Mt(function(){ut.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t){if(p=!1,K&&V){this.nativeDraggable&&(M(ut,"dragover",this._handleAutoScroll),M(ut,"dragover",T));var e=this.options;!t&&Dt(V,e.dragClass,!1),Dt(V,e.ghostClass,!0),B(V,"transform",""),_t.active=this,t&&this._appendGhost(),Ct(this,K,"start",V,K,K,Q)}else this._nulling()},_emulateDragOver:function(t){if(P){if(this._lastX===P.clientX&&this._lastY===P.clientY&&!t)return;this._lastX=P.clientX,this._lastY=P.clientY,E();for(var e=ut.elementFromPoint(P.clientX,P.clientY),n=e;e&&e.shadowRoot;)n=e=e.shadowRoot.elementFromPoint(P.clientX,P.clientY);if(n)do{if(n[dt])if(n[dt]._onDragOver({clientX:P.clientX,clientY:P.clientY,target:e,rootEl:n})&&!this.options.dragoverBubble)break;e=n}while(n=n.parentNode);V.parentNode[dt]._computeIsAligned(P),x()}},_onTouchMove:function(t){if(f){if(!t.cancelable)return;var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=G&&H(G),a=G&&r&&r.a,l=G&&r&&r.d,s=(i.clientX-f.clientX+o.x)/(a||1),c=(i.clientY-f.clientY+o.y)/(l||1),d=t.touches?"translate3d("+s+"px,"+c+"px,0)":"translate("+s+"px,"+c+"px)";if(!_t.active&&!p){if(n&&_(vt(i.clientX-this._lastX),vt(i.clientY-this._lastY))" - ], - "description": "Minimalist library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery.", - "keywords": [ - "sortable", - "reorder", - "list", - "html5", - "drag", - "and", - "drop", - "dnd" - ], - "license": "MIT", - "ignore": [ - "node_modules", - "bower_components", - "test", - "tests" - ] -} diff --git a/component.json b/component.json deleted file mode 100644 index 31a2a57e2..000000000 --- a/component.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "Sortable", - "main": "Sortable.js", - "version": "1.2.1", - "homepage": "http://rubaxa.github.io/Sortable/", - "repo": "RubaXa/Sortable", - "authors": [ - "RubaXa " - ], - "description": "Minimalist library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery.", - "keywords": [ - "sortable", - "reorder", - "list", - "html5", - "drag", - "and", - "drop", - "dnd" - ], - "license": "MIT", - "ignore": [ - "node_modules", - "bower_components", - "test", - "tests" - ], - - "scripts": [ - "Sortable.js" - ] -} diff --git a/index.html b/index.html index 5f50e04b5..f3c010e33 100644 --- a/index.html +++ b/index.html @@ -1,344 +1,375 @@ + + SortableJS + + + + - - Sortable. No jQuery. - - - + + - - - - - - Fork me on GitHub + Fork me on GitHub
        -
        - -

        The JavaScript library for modern browsers and touch devices. No jQuery.

        +
        + +

        SortableJS

        +

        JavaScript library for reorderable drag-and-drop lists

        + +
        +
        Features
        +
      • Simple list
      • +
      • Shared lists
      • +
      • Cloning
      • +
      • Disabling sorting
      • +
      • Handles
      • +
      • Filter
      • +
      • Thresholds
      • +
        Examples
        +
      • Grid
      • +
      • Nested sortables
      • +
        Framework Support
        +
    - - - -
    -
    -
    List A
    -
      -
    • бегемот
    • -
    • корм
    • -
    • антон
    • -
    • сало
    • -
    • железосталь
    • -
    • валик
    • -
    • кровать
    • -
    • краб
    • -
    +
    +

    Features

    - -
    -
    List B
    -
      -
    • казнить
    • -
    • ,
    • -
    • нельзя
    • -
    • помиловать
    • -
    +
    +
    +

    Simple list example

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    +
    new Sortable(example1, {
    +    animation: 150,
    +    ghostClass: 'blue-background-class'
    +});
    +
    -
    - - - - -
    -
    -
    Multi
    - -
    -
    Group A
    -
    - -
    +
    + +
    +

    Shared lists

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    -
    -
    Group B
    -
    - -
    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    new Sortable(example2Left, {
    +    group: 'shared', // set both lists to same group
    +    animation: 150
    +});
     
    -			
    -
    Group C
    -
    - -
    +new Sortable(example2Right, { + group: 'shared', + animation: 150 +});
    -
    -
    - - - - -
    -
    -
    Editable list
    +
    + +
    +

    Cloning

    +

    Try dragging from one list to another. The item you drag will be cloned and the clone will stay in the original list.

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    -
    -
      -
    • Оля
    • -
    • Владимир
    • -
    • Алина
    • -
    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    +
    new Sortable(example3Left, {
    +    group: {
    +        name: 'shared',
    +        pull: 'clone' // To clone: set pull to 'clone'
    +    },
    +    animation: 150
    +});
     
    -				
    +new Sortable(example3Right, {
    +    group: {
    +        name: 'shared',
    +        pull: 'clone'
    +    },
    +    animation: 150
    +});
    -
    - - - - -
    -
    -
    Advanced groups
    - -
    -
    pull & put
    -
      -
    • Meat
    • -
    • Potato
    • -
    • Tea
    • -
    +
    + +
    +

    Disabling Sorting

    +

    Try sorting the list on the left. It is not possible because it has it's sort option set to false. However, you can still drag from the list on the left to the list on the right.

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    -
    -
    only pull (clone) no reordering
    -
      -
    • Sex
    • -
    • Drugs
    • -
    • Rock'n'roll
    • -
    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    new Sortable(example4Left, {
    +    group: {
    +        name: 'shared',
    +        pull: 'clone',
    +        put: false // Do not allow items to be put into this list
    +    },
    +    animation: 150,
    +    sort: false // To disable sorting: set sort to false
    +});
     
    -			
    -
    only put
    -
      -
    • Money
    • -
    • Force
    • -
    • Agility
    • -
    +new Sortable(example4Right, { + group: 'shared', + animation: 150 +});
    - -
    -
    - - - - -
    -
    -
    Drag handle and selectable text
    - -
    -
      -
    • Select text freely
    • -
    • Drag my handle
    • -
    • Best of both worlds
    • -
    +
    + +
    +

    Handle

    +
    +
      Item 1
    +
      Item 2
    +
      Item 3
    +
      Item 4
    +
      Item 5
    +
      Item 6
    +
    +
    +
    new Sortable(example5, {
    +    handle: '.handle', // handle's class
    +    animation: 150
    +});
    - -
    -
    - - - - -
    -
    -
    AngularJS / ng-sortable
    - -
    -
    - {{remaining()}} of {{todos.length}} remaining - [ archive ] -
      -
    • - - {{todo.text}} -
    • -
    -
    - -
    +
    + +
    +

    Filter

    +

    Try dragging the item with a red background. It cannot be done, because that item is filtered out using the filter option.

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Filtered
    +
    Item 4
    +
    Item 5
    +
    +
    +
    new Sortable(example6, {
    +    filter: '.filtered', // 'filtered' class is not draggable
    +    animation: 150
    +});
    +
    +
    +
    + +
    +

    Thresholds

    +

    Try modifying the inputs below to affect the swap thresholds. You can see the swap zones of the squares colored in dark blue, while the "dead zones" (that do not cause a swap) are colored in light blue.

    +
    +
    + +
    + +
    1
    +
    + +
    + +
    2
    +
    +
    +
    + +
    + +
    +
    +
    +
    Invert Swap
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    new Sortable(example7, {
    +    swapThreshold: 1,
    +    animation: 150
    +});
    +
    +
    -
    -
    - {{remaining()}} of {{todos.length}} remaining -
      -
    • - - {{todo.text}} -
    • -
    +
    +

    Examples

    +
    +
    + +
    +

    Grid Example

    +
    +
    Item 1
    Item 2
    Item 3
    Item 4
    Item 5
    Item 6
    Item 7
    Item 8
    Item 9
    Item 10
    Item 11
    Item 12
    Item 13
    Item 14
    Item 15
    Item 16
    Item 17
    Item 18
    Item 19
    Item 20
    +
    +
    +
    + +
    +

    Nested Sortables Example

    +

    NOTE: When using nested Sortables with animation, it is recommended that the fallbackOnBody option is set to true.

    +
    +
    Item 1.1 +
    +
    Item 2.1
    +
    Item 2.2 +
    +
    Item 3.1
    +
    Item 3.2
    +
    Item 3.3
    +
    Item 3.4
    +
    +
    +
    Item 2.3
    +
    Item 2.4
    +
    +
    Item 1.2
    +
    Item 1.3
    +
    Item 1.4 +
    +
    Item 2.1
    +
    Item 2.2
    +
    Item 2.3
    +
    Item 2.4
    +
    +
    +
    Item 1.5
    - -
    -
    - +
    - - -
    -
    -
    Code example
    -
    // Simple list
    -var list = document.getElementById("my-ui-list");
    -Sortable.create(list); // That's all.
    +		
    +

    Framework Support

    +
    +
    +
    -// Grouping -var foo = document.getElementById("foo"); -Sortable.create(foo, { group: "omega" }); +

    Vue

    +

    Vue.Draggable

    -var bar = document.getElementById("bar"); -Sortable.create(bar, { group: "omega" }); +

    React

    +

    react-sortablejs

    +

    Angular

    +

    angular-sortablejs

    -// Or -var container = document.getElementById("multi"); -var sort = Sortable.create(container, { - animation: 150, // ms, animation speed moving items when sorting, `0` — without animation - handle: ".tile__title", // Restricts sort start click/touch to the specified element - draggable: ".tile", // Specifies which items inside the element should be sortable - onUpdate: function (evt/**Event*/){ - var item = evt.item; // the current dragged HTMLElement - } -}); +

    jQuery

    +

    jquery-sortablejs

    -// .. -sort.destroy(); +

    Knockout

    +

    knockout-sortablejs

    +

    Meteor

    +

    meteor-sortablejs

    -// Editable list -var editableList = Sortable.create(editable, { - filter: '.js-remove', - onFilter: function (evt) { - var el = editableList.closest(evt.item); // get dragged item - el && el.parentNode.removeChild(el); - } -}); -
    -
    - -
    -
    -
    See also
    -
    Loading…
    - -
    +

    Polymer

    +

    polymer-sortablejs

    + + - - - - + + - - - - - - - - - - diff --git a/jquery.binding.js b/jquery.binding.js deleted file mode 100644 index 9e9f4b93c..000000000 --- a/jquery.binding.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * jQuery plugin for Sortable - * @author RubaXa - * @license MIT - */ -(function (factory) { - "use strict"; - - if (typeof define === "function" && define.amd) { - define(["jquery"], factory); - } - else { - /* jshint sub:true */ - factory(jQuery); - } -})(function ($) { - "use strict"; - - - /* CODE */ - - - /** - * jQuery plugin for Sortable - * @param {Object|String} options - * @param {..*} [args] - * @returns {jQuery|*} - */ - $.fn.sortable = function (options) { - var retVal, - args = arguments; - - this.each(function () { - var $el = $(this), - sortable = $el.data('sortable'); - - if (!sortable && (options instanceof Object || !options)) { - sortable = new Sortable(this, options); - $el.data('sortable', sortable); - } - - if (sortable) { - if (options === 'widget') { - return sortable; - } - else if (options === 'destroy') { - sortable.destroy(); - $el.removeData('sortable'); - } - else if (typeof sortable[options] === 'function') { - retVal = sortable[options].apply(sortable, [].slice.call(args, 1)); - } - else if (options in sortable.options) { - retVal = sortable.option.apply(sortable, args); - } - } - }); - - return (retVal === void 0) ? this : retVal; - }; -}); diff --git a/knockout-sortable.js b/knockout-sortable.js deleted file mode 100644 index 02881970e..000000000 --- a/knockout-sortable.js +++ /dev/null @@ -1,182 +0,0 @@ -(function (factory) { - "use strict"; - if (typeof define === "function" && define.amd) { - // AMD anonymous module - define(["knockout"], factory); - } else if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { - // CommonJS module - var ko = require("knockout"); - factory(ko); - } else { - // No module loader (plain +
    +

    Features

    diff --git a/st/carbon.css b/st/carbon.css new file mode 100644 index 000000000..7b049ee54 --- /dev/null +++ b/st/carbon.css @@ -0,0 +1,78 @@ +#carbonads { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, + Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +#carbonads { + display: block; + position: relative; + overflow: hidden; +} + +#carbonads > span { + position: relative; + display: block; +} + +#carbonads a { + color: inherit; + text-decoration: none; +} + +#carbonads a:hover { + color: inherit; +} + +.carbon-wrap { + display: flex; + align-items: center; + +} + +.carbon-img { + display: block; + margin: 0; + line-height: 1; +} + +.carbon-img img { + display: block; +} + +.carbon-text { + display: flex; + margin-bottom: 12px; + position: relative; + max-width: 500px; + font-size: 16px; + line-height: 1.4; + padding: 8px 1em; + text-align: left; + align-items: center; +} + +.carbon-text:after { + display: table; + content: 'Learn More'; + white-space: nowrap; + margin-left: 20px; + background-color: hsl(0, 0%, 20%); + padding: 12px 16px; + border-radius: 3px; + line-height: 1; + color: #fff; + font-size: 14px; + font-weight: 600; +} + +.carbon-poweredby { + position: absolute; + bottom: 0; + left: 146px; + white-space: nowrap; + font-size: 10px; + text-transform: uppercase; + letter-spacing: .5px; + font-weight: 500; + color: #999 !important; +} diff --git a/st/theme.css b/st/theme.css index 3fb1ea12b..bc0495ebc 100644 --- a/st/theme.css +++ b/st/theme.css @@ -241,4 +241,8 @@ input[type=range]:focus::-ms-fill-upper { .col { padding-right: 0; margin-right: 15px; -} \ No newline at end of file +} + +.ad-container { + margin: auto; +} From 2312146f677bcf4bee6df8e818b90ea4e9142c76 Mon Sep 17 00:00:00 2001 From: owen-m1 Date: Thu, 25 Apr 2019 20:06:50 -0400 Subject: [PATCH 27/41] fixed url --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 28db0cd72..f1324e7c7 100644 --- a/index.html +++ b/index.html @@ -43,7 +43,7 @@
    Framework Support
    - +
    From ff723344176a2a66d6f5e7545d8f4fa65c92f0e0 Mon Sep 17 00:00:00 2001 From: owen-m1 Date: Sat, 1 Jun 2019 10:01:28 -0400 Subject: [PATCH 28/41] removed ads --- index.html | 5 ---- st/carbon.css | 78 --------------------------------------------------- st/theme.css | 4 --- 3 files changed, 87 deletions(-) delete mode 100644 st/carbon.css diff --git a/index.html b/index.html index f1324e7c7..840ac9b22 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,6 @@ - @@ -42,10 +41,6 @@
    Framework Support
    -
    - -
    -

    Features

    diff --git a/st/carbon.css b/st/carbon.css deleted file mode 100644 index 7b049ee54..000000000 --- a/st/carbon.css +++ /dev/null @@ -1,78 +0,0 @@ -#carbonads { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, - Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif; -} - -#carbonads { - display: block; - position: relative; - overflow: hidden; -} - -#carbonads > span { - position: relative; - display: block; -} - -#carbonads a { - color: inherit; - text-decoration: none; -} - -#carbonads a:hover { - color: inherit; -} - -.carbon-wrap { - display: flex; - align-items: center; - -} - -.carbon-img { - display: block; - margin: 0; - line-height: 1; -} - -.carbon-img img { - display: block; -} - -.carbon-text { - display: flex; - margin-bottom: 12px; - position: relative; - max-width: 500px; - font-size: 16px; - line-height: 1.4; - padding: 8px 1em; - text-align: left; - align-items: center; -} - -.carbon-text:after { - display: table; - content: 'Learn More'; - white-space: nowrap; - margin-left: 20px; - background-color: hsl(0, 0%, 20%); - padding: 12px 16px; - border-radius: 3px; - line-height: 1; - color: #fff; - font-size: 14px; - font-weight: 600; -} - -.carbon-poweredby { - position: absolute; - bottom: 0; - left: 146px; - white-space: nowrap; - font-size: 10px; - text-transform: uppercase; - letter-spacing: .5px; - font-weight: 500; - color: #999 !important; -} diff --git a/st/theme.css b/st/theme.css index bc0495ebc..9ee899929 100644 --- a/st/theme.css +++ b/st/theme.css @@ -242,7 +242,3 @@ input[type=range]:focus::-ms-fill-upper { padding-right: 0; margin-right: 15px; } - -.ad-container { - margin: auto; -} From 4b3b7e06547bdd0bd1da724127cec613faf43a76 Mon Sep 17 00:00:00 2001 From: owen-m1 Date: Thu, 6 Jun 2019 19:29:00 -0400 Subject: [PATCH 29/41] 1.10.0-rc1 --- Sortable.js | 6091 ++++++++++++++++++++++++++++------------------- Sortable.min.js | 5 +- index.html | 59 +- st/app.js | 19 +- st/theme.css | 10 + 5 files changed, 3725 insertions(+), 2459 deletions(-) diff --git a/Sortable.js b/Sortable.js index eeb0ba4c7..165f1bf59 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,2460 +1,3643 @@ /**! - * Sortable - * @author RubaXa - * @author owenm + * Sortable 1.10.0-rc1 + * @author RubaXa + * @author owenm * @license MIT */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.Sortable = factory()); +}(this, function () { 'use strict'; + + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + + return _typeof(obj); + } + + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + } + + function _extends() { + _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); + } + + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } + + return target; + } + + function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; + } + + function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; + } + + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } + + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } + } + + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } + + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } + + var version = "1.10.0-rc1"; + + function userAgent(pattern) { + return !!navigator.userAgent.match(pattern); + } + + var IE11OrLess = + /*@__PURE__*/ + userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile)/i); + var Edge = + /*@__PURE__*/ + userAgent(/Edge/i); + var FireFox = + /*@__PURE__*/ + userAgent(/firefox/i); + var Safari = + /*@__PURE__*/ + userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); + var IOS = + /*@__PURE__*/ + userAgent(/iP(ad|od|hone)/i); + + var captureMode = { + capture: false, + passive: false + }; + + function on(el, event, fn) { + el.addEventListener(event, fn, !IE11OrLess && captureMode); + } + + function off(el, event, fn) { + el.removeEventListener(event, fn, !IE11OrLess && captureMode); + } + + function matches( + /**HTMLElement*/ + el, + /**String*/ + selector) { + if (!selector) return; + selector[0] === '>' && (selector = selector.substring(1)); + + if (el) { + try { + if (el.matches) { + return el.matches(selector); + } else if (el.msMatchesSelector) { + return el.msMatchesSelector(selector); + } else if (el.webkitMatchesSelector) { + return el.webkitMatchesSelector(selector); + } + } catch (_) { + return false; + } + } + + return false; + } + + function getParentOrHost(el) { + return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; + } + + function closest( + /**HTMLElement*/ + el, + /**String*/ + selector, + /**HTMLElement*/ + ctx, includeCTX) { + if (el) { + ctx = ctx || document; + + do { + if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { + return el; + } + + if (el === ctx) break; + /* jshint boss:true */ + } while (el = getParentOrHost(el)); + } + + return null; + } + + var R_SPACE = /\s+/g; + + function toggleClass(el, name, state) { + if (el && name) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } + } + + function css(el, prop, val) { + var style = el && el.style; + + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } else if (el.currentStyle) { + val = el.currentStyle; + } + + return prop === void 0 ? val : val[prop]; + } else { + if (!(prop in style) && prop.indexOf('webkit') === -1) { + prop = '-webkit-' + prop; + } + + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } + } + + function matrix(el, selfOnly) { + var appliedTransforms = ''; + + do { + var transform = css(el, 'transform'); + + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ + + } while (!selfOnly && (el = el.parentNode)); + + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + /*jshint -W056 */ + + return matrixFn && new matrixFn(appliedTransforms); + } + + function find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), + i = 0, + n = list.length; + + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } + + return list; + } + + return []; + } + + function getWindowScrollingElement() { + if (IE11OrLess) { + return document.documentElement; + } else { + return document.scrollingElement; + } + } + /** + * Returns the "bounding client rect" of given element + * @param {HTMLElement} el The element whose boundingClientRect is wanted + * @param {[Boolean]} relativeToContainingBlock Whether the rect should be relative to the containing block of (including) the container + * @param {[Boolean]} relativeToNonStaticParent Whether the rect should be relative to the relative parent of (including) the contaienr + * @param {[Boolean]} undoScale Whether the container's scale() should be undone + * @param {[HTMLElement]} container The parent the element will be placed in + * @return {Object} The boundingClientRect of el, with specified adjustments + */ + + + function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { + if (!el.getBoundingClientRect && el !== window) return; + var elRect, top, left, bottom, right, height, width; + + if (el !== window && el !== getWindowScrollingElement()) { + elRect = el.getBoundingClientRect(); + top = elRect.top; + left = elRect.left; + bottom = elRect.bottom; + right = elRect.right; + height = elRect.height; + width = elRect.width; + } else { + top = 0; + left = 0; + bottom = window.innerHeight; + right = window.innerWidth; + height = window.innerHeight; + width = window.innerWidth; + } + + if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { + // Adjust for translate() + container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 + + if (!IE11OrLess) { + do { + if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { + var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + + top -= containerRect.top + parseInt(css(container, 'border-top-width')); + left -= containerRect.left + parseInt(css(container, 'border-left-width')); + bottom = top + elRect.height; + right = left + elRect.width; + break; + } + /* jshint boss:true */ + + } while (container = container.parentNode); + } + } + + if (undoScale && el !== window) { + // Adjust for scale() + var elMatrix = matrix(container || el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; + + if (elMatrix) { + top /= scaleY; + left /= scaleX; + width /= scaleX; + height /= scaleY; + bottom = top + height; + right = left + width; + } + } + + return { + top: top, + left: left, + bottom: bottom, + right: right, + width: width, + height: height + }; + } + /** + * Checks if a side of an element is scrolled past a side of its parents + * @param {HTMLElement} el The element who's side being scrolled out of view is in question + * @param {[DOMRect]} rect Optional rect of `el` to use + * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') + * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') + * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element + */ + + + function isScrolledPast(el, rect, elSide, parentSide) { + var parent = getParentAutoScrollElement(el, true), + elSideVal = (rect ? rect : getRect(el))[elSide]; + /* jshint boss:true */ + + while (parent) { + var parentSideVal = getRect(parent)[parentSide], + visible = void 0; + + if (parentSide === 'top' || parentSide === 'left') { + visible = elSideVal >= parentSideVal; + } else { + visible = elSideVal <= parentSideVal; + } + + if (!visible) return parent; + if (parent === getWindowScrollingElement()) break; + parent = getParentAutoScrollElement(parent, false); + } + + return false; + } + /** + * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) + * and non-draggable elements + * @param {HTMLElement} el The parent element + * @param {Number} childNum The index of the child + * @param {Object} options Parent Sortable's options + * @return {HTMLElement} The child at index childNum, or null if not found + */ + + + function getChild(el, childNum, options) { + var currentChild = 0, + i = 0, + children = el.children; + + while (i < children.length) { + if (children[i].style.display !== 'none' && children[i] !== Sortable$1.ghost && children[i] !== Sortable$1.dragged && closest(children[i], options.draggable, el, false)) { + if (currentChild === childNum) { + return children[i]; + } + + currentChild++; + } + + i++; + } + + return null; + } + /** + * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) + * @param {HTMLElement} el Parent element + * @param {selector} selector Any other elements that should be ignored + * @return {HTMLElement} The last child, ignoring ghostEl + */ + + + function lastChild(el, selector) { + var last = el.lastElementChild; + + while (last && (last === Sortable$1.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + last = last.previousElementSibling; + } + + return last || null; + } + /** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + + + function index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + /* jshint boss:true */ + + + while (el = el.previousElementSibling) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable$1.clone && (!selector || matches(el, selector))) { + index++; + } + } + + return index; + } + /** + * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. + * The value is returned in real pixels. + * @param {HTMLElement} el + * @return {Array} Offsets in the format of [left, top] + */ + + + function getRelativeScrollOffset(el) { + var offsetLeft = 0, + offsetTop = 0, + winScroller = getWindowScrollingElement(); + + if (el) { + do { + var elMatrix = matrix(el), + scaleX = elMatrix.a, + scaleY = elMatrix.d; + offsetLeft += el.scrollLeft * scaleX; + offsetTop += el.scrollTop * scaleY; + } while (el !== winScroller && (el = el.parentNode)); + } + + return [offsetLeft, offsetTop]; + } + /** + * Returns the index of the object within the given array + * @param {Array} arr Array that may or may not hold the object + * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find + * @return {Number} The index of the object in the array, or -1 + */ + + + function indexOfObject(arr, obj) { + for (var i in arr) { + for (var key in obj) { + if (obj[key] === arr[i][key]) return Number(i); + } + } + + return -1; + } + + function getParentAutoScrollElement(el, includeSelf) { + // skip to window + if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); + var elem = el; + var gotSelf = false; + + do { + // we don't need to get elem css if it isn't even overflowing in the first place (performance) + if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { + var elemCSS = css(elem); + + if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { + if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); + if (gotSelf || includeSelf) return elem; + gotSelf = true; + } + } + /* jshint boss:true */ + + } while (elem = elem.parentNode); + + return getWindowScrollingElement(); + } + + function extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; + } + + function isRectEqual(rect1, rect2) { + return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); + } + + var _throttleTimeout; + + function throttle(callback, ms) { + return function () { + if (!_throttleTimeout) { + var args = arguments, + _this = this; + + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + _throttleTimeout = setTimeout(function () { + _throttleTimeout = void 0; + }, ms); + } + }; + } + + function cancelThrottle() { + clearTimeout(_throttleTimeout); + _throttleTimeout = void 0; + } + + function scrollBy(el, x, y) { + el.scrollLeft += x; + el.scrollTop += y; + } + + function clone(el) { + var Polymer = window.Polymer; + var $ = window.jQuery || window.Zepto; + + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } else if ($) { + return $(el).clone(true)[0]; + } else { + return el.cloneNode(true); + } + } + + function setRect(el, rect) { + css(el, 'position', 'absolute'); + css(el, 'top', rect.top); + css(el, 'left', rect.left); + css(el, 'width', rect.width); + css(el, 'height', rect.height); + } + + function unsetRect(el) { + css(el, 'position', ''); + css(el, 'top', ''); + css(el, 'left', ''); + css(el, 'width', ''); + css(el, 'height', ''); + } + + var expando = 'Sortable' + new Date().getTime(); + + function AnimationStateManager() { + var animationStates = [], + animationCallbackId; + return { + captureAnimationState: function captureAnimationState() { + animationStates = []; + if (!this.options.animation) return; + var children = [].slice.call(this.el.children); + + for (var i in children) { + if (css(children[i], 'display') === 'none' || children[i] === Sortable$1.ghost) continue; + animationStates.push({ + target: children[i], + rect: getRect(children[i]) + }); + var fromRect = getRect(children[i]); // If animating: compensate for current animation + + if (children[i].thisAnimationDuration) { + var childMatrix = matrix(children[i], true); + + if (childMatrix) { + fromRect.top -= childMatrix.f; + fromRect.left -= childMatrix.e; + } + } + + children[i].fromRect = fromRect; + } + }, + addAnimationState: function addAnimationState(state) { + animationStates.push(state); + }, + removeAnimationState: function removeAnimationState(target) { + animationStates.splice(indexOfObject(animationStates, { + target: target + }), 1); + }, + animateAll: function animateAll(callback) { + if (!this.options.animation) { + clearTimeout(animationCallbackId); + if (typeof callback === 'function') callback(); + return; + } + + var animating = false, + animationTime = 0; + + for (var i in animationStates) { + var time = 0, + target = animationStates[i].target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = animationStates[i].rect, + targetMatrix = matrix(target, true); + + if (targetMatrix) { + // Compensate for current animation + toRect.top -= targetMatrix.f; + toRect.left -= targetMatrix.e; + } + + target.toRect = toRect; // If element is scrolled out of view: Do not animate + + if ((isScrolledPast(target, toRect, 'bottom', 'top') || isScrolledPast(target, toRect, 'top', 'bottom') || isScrolledPast(target, toRect, 'right', 'left') || isScrolledPast(target, toRect, 'left', 'right')) && (isScrolledPast(target, animatingRect, 'bottom', 'top') || isScrolledPast(target, animatingRect, 'top', 'bottom') || isScrolledPast(target, animatingRect, 'right', 'left') || isScrolledPast(target, animatingRect, 'left', 'right')) && (isScrolledPast(target, fromRect, 'bottom', 'top') || isScrolledPast(target, fromRect, 'top', 'bottom') || isScrolledPast(target, fromRect, 'right', 'left') || isScrolledPast(target, fromRect, 'left', 'right'))) continue; + + if (target.thisAnimationDuration) { + // Could also check if animatingRect is between fromRect and toRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { + // If returning to same place as started from animation and on same axis + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, this.options); + } + } // if fromRect != toRect: animate + + + if (!isRectEqual(toRect, fromRect)) { + target.prevFromRect = fromRect; + target.prevToRect = toRect; + + if (!time) { + time = this.options.animation; + } + + this.animate(target, animatingRect, time); + } + + if (time) { + animating = true; + animationTime = Math.max(animationTime, time); + clearTimeout(target.animationResetTimer); + target.animationResetTimer = setTimeout(function () { + this.animationStates[this.i].target.animationTime = 0; + this.animationStates[this.i].target.prevFromRect = null; + this.animationStates[this.i].target.fromRect = null; + this.animationStates[this.i].target.prevToRect = null; + this.animationStates[this.i].target.thisAnimationDuration = null; + }.bind({ + animationStates: animationStates, + i: Number(i) + }), time); + target.thisAnimationDuration = time; + } + } + + clearTimeout(animationCallbackId); + + if (!animating) { + if (typeof callback === 'function') callback(); + } else { + animationCallbackId = setTimeout(function () { + if (typeof callback === 'function') callback(); + }, animationTime); + } + + animationStates = []; + }, + animate: function animate(target, prev, duration) { + if (duration) { + css(target, 'transition', ''); + css(target, 'transform', ''); + var currentRect = getRect(target), + elMatrix = matrix(this.el), + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (prev.left - currentRect.left) / (scaleX || 1), + translateY = (prev.top - currentRect.top) / (scaleY || 1); + target.animatingX = !!translateX; + target.animatingY = !!translateY; + css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); + repaint(target); // repaint + + css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); + css(target, 'transform', 'translate3d(0,0,0)'); + typeof target.animated === 'number' && clearTimeout(target.animated); + target.animated = setTimeout(function () { + css(target, 'transition', ''); + css(target, 'transform', ''); + target.animated = false; + target.animatingX = false; + target.animatingY = false; + }, duration); + } + } + }; + } + + function repaint(target) { + return target.offsetWidth; + } + + function calculateRealTime(animatingRect, fromRect, toRect, options) { + return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; + } + + var plugins = []; + var defaults = { + initializeByDefault: true + }; + var PluginManager = { + mount: function mount(plugin) { + // Set default static properties + for (var option in defaults) { + !(option in plugin) && (plugin[option] = defaults[option]); + } + + plugins.push(plugin); + }, + pluginEvent: function pluginEvent(eventName, sortable, evt) { + this.eventCanceled = false; + var eventNameGlobal = eventName + 'Global'; + + for (var i in plugins) { + if (!sortable[plugins[i].pluginName]) continue; // Fire global events if it exists in this sortable + + if (sortable[plugins[i].pluginName][eventNameGlobal]) { + this.eventCanceled = !!sortable[plugins[i].pluginName][eventNameGlobal](_objectSpread({ + sortable: sortable + }, evt)); + } // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined + + + if (sortable.options[plugins[i].pluginName] && sortable[plugins[i].pluginName][eventName]) { + this.eventCanceled = this.eventCanceled || !!sortable[plugins[i].pluginName][eventName](_objectSpread({ + sortable: sortable + }, evt)); + } + } + }, + initializePlugins: function initializePlugins(sortable, el, defaults) { + for (var i in plugins) { + var pluginName = plugins[i].pluginName; + if (!sortable.options[pluginName] && !plugins[i].initializeByDefault) continue; + var initialized = new plugins[i](sortable, el); + initialized.sortable = sortable; + sortable[pluginName] = initialized; // Add default options from plugin + + _extends(defaults, initialized.options); + } + + for (var option in sortable.options) { + var modified = this.modifyOption(sortable, option, sortable.options[option]); + + if (typeof modified !== 'undefined') { + sortable.options[option] = modified; + } + } + }, + getEventOptions: function getEventOptions(name, sortable) { + var eventOptions = {}; + + for (var i in plugins) { + if (typeof plugins[i].eventOptions !== 'function') continue; + + _extends(eventOptions, plugins[i].eventOptions.call(sortable, name)); + } + + return eventOptions; + }, + modifyOption: function modifyOption(sortable, name, value) { + var modifiedValue; + + for (var i in plugins) { + // Plugin must exist on the Sortable + if (!sortable[plugins[i].pluginName]) continue; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + + if (plugins[i].optionListeners && typeof plugins[i].optionListeners[name] === 'function') { + modifiedValue = plugins[i].optionListeners[name].call(sortable[plugins[i].pluginName], value); + } + } + + return modifiedValue; + } + }; + + function dispatchEvent(_ref) { + var sortable = _ref.sortable, + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + eventOptions = _ref.eventOptions; + sortable = sortable || rootEl[expando]; + var evt, + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent(name, { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(name, true, true); + } + + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = oldIndex; + evt.newIndex = newIndex; + evt.oldDraggableIndex = oldDraggableIndex; + evt.newDraggableIndex = newDraggableIndex; + evt.originalEvent = originalEvent; + evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; + + var allEventOptions = _objectSpread({}, eventOptions, PluginManager.getEventOptions(name, sortable)); + + for (var option in allEventOptions) { + evt[option] = allEventOptions[option]; + } + + if (rootEl) { + rootEl.dispatchEvent(evt); + } + + if (options[onName]) { + options[onName].call(sortable, evt); + } + } + + var pluginEvent = function pluginEvent(eventName, sortable) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, ["evt"]); + + PluginManager.pluginEvent.bind(Sortable$1)(eventName, sortable, _objectSpread({ + dragEl: dragEl, + parentEl: parentEl, + ghostEl: ghostEl, + rootEl: rootEl, + nextEl: nextEl, + lastDownEl: lastDownEl, + cloneEl: cloneEl, + cloneHidden: cloneHidden, + dragStarted: moved, + putSortable: putSortable, + activeSortable: Sortable$1.active, + originalEvent: originalEvent, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + hideGhostForTarget: _hideGhostForTarget, + unhideGhostForTarget: _unhideGhostForTarget, + cloneNowHidden: function cloneNowHidden() { + cloneHidden = true; + }, + cloneNowShown: function cloneNowShown() { + cloneHidden = false; + }, + dispatchSortableEvent: function dispatchSortableEvent(name) { + _dispatchEvent({ + sortable: sortable, + name: name, + originalEvent: originalEvent + }); + } + }, data)); + }; + + function _dispatchEvent(info) { + dispatchEvent(_objectSpread({ + putSortable: putSortable, + cloneEl: cloneEl, + targetEl: dragEl, + rootEl: rootEl, + oldIndex: oldIndex, + oldDraggableIndex: oldDraggableIndex, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex + }, info)); + } + + if (typeof window === "undefined" || !window.document) { + throw new Error("Sortable.js requires a window with a document"); + } + + var dragEl, + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely + ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) + _silent = false, + savedInputChecked = []; + /** @const */ + + var PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors + supportDraggable = 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + // false when <= IE11 + if (IE11OrLess) { + return false; + } + + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + }(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), + elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), + child1 = getChild(el, 0, options), + child2 = getChild(el, 1, options), + firstChildCSS = child1 && css(child1), + secondChildCSS = child2 && css(child2), + firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, + secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; + + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + + if (child1 && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; + }, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, + dragElOppLength = vertical ? dragRect.width : dragRect.height, + targetS1Opp = vertical ? targetRect.left : targetRect.top, + targetS2Opp = vertical ? targetRect.right : targetRect.bottom, + targetOppLength = vertical ? targetRect.width : targetRect.height; + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; + }, + + /** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ + _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + for (var i in sortables) { + if (lastChild(sortables[i])) continue; + var rect = getRect(sortables[i]), + threshold = sortables[i][expando].options.emptyInsertThreshold, + insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, + insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; + + if (threshold && insideHorizontally && insideVertically) { + return sortables[i]; + } + } + }, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; + }, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } + }, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } + }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position + + + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); + + var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { + if (dragEl) { + evt = evt.touches ? evt.touches[0] : evt; + + var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); + + if (nearest) { + // Create imitation event + var event = {}; + + for (var i in evt) { + event[i] = evt[i]; + } + + event.target = event.rootEl = nearest; + event.preventDefault = void 0; + event.stopPropagation = void 0; + + nearest[expando]._onDragOver(event); + } + } + }; + + var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { + if (dragEl) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + } + }; + /** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + + + function Sortable$1(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); + } + + this.el = el; // root element + + this.options = options = _extends({}, options); // Export instance + + el[expando] = this; + var defaults = { + group: null, + sort: true, + disabled: false, + store: null, + handle: null, + draggable: /^[uo]l$/i.test(el.nodeName) ? '>li' : '>*', + swapThreshold: 1, + // percentage; 0 <= x <= 1 + invertSwap: false, + // invert always + invertedSwapThreshold: null, + // will be set to same as swapThreshold if default + removeCloneOnHide: true, + direction: function direction() { + return _detectDirection(el, this.options); + }, + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + easing: null, + setData: function setData(dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + delayOnTouchOnly: false, + touchStartThreshold: Number.parseInt(window.devicePixelRatio, 10) || 1, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: { + x: 0, + y: 0 + }, + supportPointer: Sortable$1.supportPointer !== false && 'PointerEvent' in window, + emptyInsertThreshold: 5 + }; + PluginManager.initializePlugins(this, el, defaults); // Set default options + + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); // Bind all private methods + + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } // Setup drag mode + + + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + if (this.nativeDraggable) { + // Touch start threshold cannot be greater than the native dragstart threshold + this.options.touchStartThreshold = 1; + } // Bind events + + + if (options.supportPointer) { + on(el, 'pointerdown', this._onTapStart); + } else { + on(el, 'mousedown', this._onTapStart); + on(el, 'touchstart', this._onTapStart); + } + + if (this.nativeDraggable) { + on(el, 'dragover', this); + on(el, 'dragenter', this); + } + + sortables.push(this.el); // Restore sorting + + options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + + _extends(this, AnimationStateManager()); + } + + Sortable$1.prototype = + /** @lends Sortable.prototype */ + { + constructor: Sortable$1, + _isOutsideThisEl: function _isOutsideThisEl(target) { + if (!this.el.contains(target) && target !== this.el) { + lastTarget = null; + } + }, + _getDirection: function _getDirection(evt, target) { + return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; + }, + _onTapStart: function _onTapStart( + /** Event|TouchEvent */ + evt) { + if (!evt.cancelable) return; + + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0], + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + + _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + + + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button and enabled + } // cancel dnd if original target is content editable + + + if (originalTarget.isContentEditable) { + return; + } + + target = closest(target, options.draggable, el, false); + + if (target && target.animated) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } // Get the index of the dragged element within its parent + + + oldIndex = index(target); + oldDraggableIndex = index(target, options.draggable); // Check filter + + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent({ + sortable: _this, + rootEl: originalTarget, + name: 'filter', + targetEl: target, + toEl: el, + fromEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = closest(originalTarget, criteria.trim(), el, false); + + if (criteria) { + _dispatchEvent({ + sortable: _this, + rootEl: criteria, + name: 'filter', + targetEl: target, + fromEl: el, + toEl: el + }); + + pluginEvent('filter', _this, { + evt: evt + }); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.cancelable && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !closest(originalTarget, options.handle, el, false)) { + return; + } // Prepare `dragstart` + + + this._prepareDragStart(evt, touch, target); + }, + _prepareDragStart: function _prepareDragStart( + /** Event */ + evt, + /** Touch */ + touch, + /** HTMLElement */ + target) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && target.parentNode === el) { + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + Sortable$1.dragged = dragEl; + tapEvt = { + target: dragEl, + clientX: (touch || evt).clientX, + clientY: (touch || evt).clientY + }; + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + dragEl.style['will-change'] = 'all'; + + dragStartFn = function dragStartFn() { + pluginEvent('delayEnded', _this, { + evt: evt + }); + + if (Sortable$1.eventCanceled) { + _this._onDrop(); + + return; + } // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + + + _this._disableDelayedDragEvents(); + + if (!FireFox && _this.nativeDraggable) { + dragEl.draggable = true; + } // Bind the events: dragstart/dragend + + + _this._triggerDragStart(evt, touch); // Drag start event + + + _dispatchEvent({ + sortable: _this, + name: 'choose', + originalEvent: evt + }); // Chosen item + + + toggleClass(dragEl, options.chosenClass, true); + }; // Disable "draggable" + + + options.ignore.split(',').forEach(function (criteria) { + find(dragEl, criteria.trim(), _disableDraggable); + }); + on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + + if (FireFox && this.nativeDraggable) { + this.options.touchStartThreshold = 4; + dragEl.draggable = true; + } + + pluginEvent('delayStart', this, { + evt: evt + }); // Delay is impossible for native DnD in Edge or IE + + if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { + if (Sortable$1.eventCanceled) { + this._onDrop(); + + return; + } // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + + + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); + on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); + options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + } + }, + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( + /** TouchEvent|PointerEvent **/ + e) { + var touch = e.touches ? e.touches[0] : e; + + if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { + this._disableDelayedDrag(); + } + }, + _disableDelayedDrag: function _disableDelayedDrag() { + dragEl && _disableDraggable(dragEl); + clearTimeout(this._dragStartTimer); + + this._disableDelayedDragEvents(); + }, + _disableDelayedDragEvents: function _disableDelayedDragEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._disableDelayedDrag); + off(ownerDocument, 'touchend', this._disableDelayedDrag); + off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); + off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); + }, + _triggerDragStart: function _triggerDragStart( + /** Event */ + evt, + /** Touch */ + touch) { + touch = touch || (evt.pointerType == 'touch' ? evt : null); + + if (!this.nativeDraggable || touch) { + if (this.options.supportPointer) { + on(document, 'pointermove', this._onTouchMove); + } else if (touch) { + on(document, 'touchmove', this._onTouchMove); + } else { + on(document, 'mousemove', this._onTouchMove); + } + } else { + on(dragEl, 'dragend', this); + on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) {} + }, + _dragStarted: function _dragStarted(fallback, evt) { + + awaitingDragStarted = false; + + if (rootEl && dragEl) { + pluginEvent('dragStarted', this, { + evt: evt + }); + + if (this.nativeDraggable) { + on(document, 'dragover', _checkOutsideTargetEl); + } + + var options = this.options; // Apply effect + + !fallback && toggleClass(dragEl, options.dragClass, false); + toggleClass(dragEl, options.ghostClass, true); + Sortable$1.active = this; + fallback && this._appendGhost(); // Drag start event + + _dispatchEvent({ + sortable: this, + name: 'start', + originalEvent: evt + }); + } else { + this._nulling(); + } + }, + _emulateDragOver: function _emulateDragOver() { + if (touchEvt) { + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + _hideGhostForTarget(); + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + + while (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + if (target === parent) break; + parent = target; + } + + dragEl.parentNode[expando]._isOutsideThisEl(target); + + if (parent) { + do { + if (parent[expando]) { + var inserted = void 0; + inserted = parent[expando]._onDragOver({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + + if (inserted && !this.options.dragoverBubble) { + break; + } + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + _unhideGhostForTarget(); + } + }, + _onTouchMove: function _onTouchMove( + /**TouchEvent*/ + evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1), + translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; // only set the status to dragging, when we are actually dragging + + if (!Sortable$1.active && !awaitingDragStarted) { + if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { + return; + } + + this._onDragStart(evt, true); + } + + touchEvt = touch; + css(ghostEl, 'webkitTransform', translate3d); + css(ghostEl, 'mozTransform', translate3d); + css(ghostEl, 'msTransform', translate3d); + css(ghostEl, 'transform', translate3d); + evt.cancelable && evt.preventDefault(); + } + }, + _appendGhost: function _appendGhost() { + // Bug if using scale(): https://stackoverflow.com/questions/2637058 + // Not being adjusted for + if (!ghostEl) { + var container = this.options.fallbackOnBody ? document.body : rootEl, + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; // Position absolutely + + if (PositionGhostAbsolutely) { + // Get relatively positioned parent + ghostRelativeParent = container; + + while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { + ghostRelativeParent = ghostRelativeParent.parentNode; + } + + if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { + if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); + rect.top += ghostRelativeParent.scrollTop; + rect.left += ghostRelativeParent.scrollLeft; + } else { + ghostRelativeParent = getWindowScrollingElement(); + } + + ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); + } + + ghostEl = dragEl.cloneNode(true); + toggleClass(ghostEl, options.ghostClass, false); + toggleClass(ghostEl, options.fallbackClass, true); + toggleClass(ghostEl, options.dragClass, true); + css(ghostEl, 'transition', ''); + css(ghostEl, 'transform', ''); + css(ghostEl, 'box-sizing', 'border-box'); + css(ghostEl, 'margin', 0); + css(ghostEl, 'top', rect.top); + css(ghostEl, 'left', rect.left); + css(ghostEl, 'width', rect.width); + css(ghostEl, 'height', rect.height); + css(ghostEl, 'opacity', '0.8'); + css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); + css(ghostEl, 'zIndex', '100000'); + css(ghostEl, 'pointerEvents', 'none'); + Sortable$1.ghost = ghostEl; + container.appendChild(ghostEl); + } + }, + _onDragStart: function _onDragStart( + /**Event*/ + evt, + /**boolean*/ + fallback) { + var _this = this; + + var dataTransfer = evt.dataTransfer; + var options = _this.options; + pluginEvent('dragStart', this, { + evt: evt + }); + + if (Sortable$1.eventCanceled) { + this._onDrop(); + + return; + } + + pluginEvent('setupClone', this); + + if (!Sortable$1.eventCanceled) { + cloneEl = clone(dragEl); + cloneEl.draggable = false; + cloneEl.style['will-change'] = ''; + + this._hideClone(); + + toggleClass(cloneEl, this.options.chosenClass, false); + Sortable$1.clone = cloneEl; + } // #1143: IFrame support workaround + + + _this.cloneId = _nextTick(function () { + pluginEvent('clone', _this); + if (Sortable$1.eventCanceled) return; + + if (!_this.options.removeCloneOnHide) { + rootEl.insertBefore(cloneEl, dragEl); + } + + _this._hideClone(); + + _dispatchEvent({ + sortable: _this, + name: 'clone' + }); + }); + !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + + if (fallback) { + ignoreNextClick = true; + _this._loopId = setInterval(_this._emulateDragOver, 50); + } else { + // Undo what was set in _prepareDragStart before drag started + off(document, 'mouseup', _this._onDrop); + off(document, 'touchend', _this._onDrop); + off(document, 'touchcancel', _this._onDrop); + + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + on(document, 'drop', _this); // #1276 fix: + + css(dragEl, 'transform', 'translateZ(0)'); + } + + awaitingDragStarted = true; + _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); + on(document, 'selectstart', _this); + moved = true; + + if (Safari) { + css(document.body, 'user-select', 'none'); + } + }, + // Returns true - if no further action is needed (either inserted or another condition) + _onDragOver: function _onDragOver( + /**Event*/ + evt) { + var el = this.el, + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable$1.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; + + if (_silent) return; + + function dragOverEvent(name, extra) { + pluginEvent(name, _this, _objectSpread({ + evt: evt, + isOwner: isOwner, + axis: vertical ? 'vertical' : 'horizontal', + revert: revert, + dragRect: dragRect, + targetRect: targetRect, + canSort: canSort, + fromSortable: fromSortable, + target: target, + completed: completed, + onMove: function onMove(target, after) { + return _onMove(rootEl, el, dragEl, dragRect, target, getRect(target), evt, after); + }, + changed: changed + }, extra)); + } // Capture animation state + + + function capture() { + dragOverEvent('dragOverAnimationCapture'); + + _this.captureAnimationState(); + + if (_this !== fromSortable) { + fromSortable.captureAnimationState(); + } + } // Return invocation when dragEl is inserted (or completed) + + + function completed(insertion) { + dragOverEvent('dragOverCompleted', { + insertion: insertion + }); + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } else { + activeSortable._showClone(_this); + } + + if (_this !== fromSortable) { + // Set ghost class to new sortable's ghost class + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); + toggleClass(dragEl, options.ghostClass, true); + } + + if (putSortable !== _this && _this !== Sortable$1.active) { + putSortable = _this; + } else if (_this === Sortable$1.active && putSortable) { + putSortable = null; + } // Animation + + + if (fromSortable === _this) { + _this._ignoreWhileAnimating = target; + } + + _this.animateAll(function () { + dragOverEvent('dragOverAnimationComplete'); + _this._ignoreWhileAnimating = null; + }); + + if (_this !== fromSortable) { + fromSortable.animateAll(); + fromSortable._ignoreWhileAnimating = null; + } + } // Null lastTarget if it is not inside a previously swapped element + + + if (target === dragEl && !dragEl.animated || target === el && !target.animated) { + lastTarget = null; + } // no bubbling and not fallback + + + if (!options.dragoverBubble && !evt.rootEl && target !== document) { + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted + + + !insertion && nearestEmptyInsertDetectEvent(evt); + } + + !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); + return completedFired = true; + } // Call when dragEl has been inserted + + + function changed() { + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + _dispatchEvent({ + sortable: _this, + name: 'change', + toEl: el, + newIndex: newIndex, + newDraggableIndex: newDraggableIndex, + originalEvent: evt + }); + } + + if (evt.preventDefault !== void 0) { + evt.cancelable && evt.preventDefault(); + } + + target = closest(target, options.draggable, el, true); + dragOverEvent('dragOver'); + if (Sortable$1.eventCanceled) return completedFired; -(function sortableModule(factory) { - "use strict"; + if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { + return completed(false); + } - if (typeof define === "function" && define.amd) { - define(factory); - } - else if (typeof module != "undefined" && typeof module.exports != "undefined") { - module.exports = factory(); - } - else { - /* jshint sub:true */ - window["Sortable"] = factory(); - } -})(function sortableFactory() { - "use strict"; - - if (typeof window === "undefined" || !window.document) { - return function sortableError() { - throw new Error("Sortable.js requires a window with a document"); - }; - } + ignoreNextClick = false; - var dragEl, - parentEl, - ghostEl, - cloneEl, - rootEl, - nextEl, - lastDownEl, - - scrollEl, - scrollParentEl, - scrollCustomFn, - - oldIndex, - newIndex, - oldDraggableIndex, - newDraggableIndex, - - activeGroup, - putSortable, - - autoScrolls = [], - scrolling = false, - - awaitingDragStarted = false, - ignoreNextClick = false, - sortables = [], - - pointerElemChangedInterval, - lastPointerElemX, - lastPointerElemY, - - tapEvt, - touchEvt, - - moved, - - - lastTarget, - lastDirection, - pastFirstInvertThresh = false, - isCircumstantialInvert = false, - lastMode, // 'swap' or 'insert' - - targetMoveDistance, - - // For positioning ghost absolutely - ghostRelativeParent, - ghostRelativeParentInitialScroll = [], // (left, top) - - realDragElRect, // dragEl rect after current animation - - /** @const */ - R_SPACE = /\s+/g, - - expando = 'Sortable' + (new Date).getTime(), - - win = window, - document = win.document, - parseInt = win.parseInt, - setTimeout = win.setTimeout, - - $ = win.jQuery || win.Zepto, - Polymer = win.Polymer, - - captureMode = { - capture: false, - passive: false - }, - - IE11OrLess = !!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie|iemobile)/i), - Edge = !!navigator.userAgent.match(/Edge/i), - FireFox = !!navigator.userAgent.match(/firefox/i), - Safari = !!(navigator.userAgent.match(/safari/i) && !navigator.userAgent.match(/chrome/i) && !navigator.userAgent.match(/android/i)), - IOS = !!(navigator.userAgent.match(/iP(ad|od|hone)/i)), - - PositionGhostAbsolutely = IOS, - - CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', - - // This will not pass for IE9, because IE9 DnD only works on anchors - supportDraggable = ('draggable' in document.createElement('div')), - - supportCssPointerEvents = (function() { - // false when <= IE11 - if (IE11OrLess) { - return false; - } - var el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - })(), - - _silent = false, - _alignedSilent = false, - - abs = Math.abs, - min = Math.min, - max = Math.max, - - savedInputChecked = [], - - _detectDirection = function(el, options) { - var elCSS = _css(el), - elWidth = parseInt(elCSS.width) - - parseInt(elCSS.paddingLeft) - - parseInt(elCSS.paddingRight) - - parseInt(elCSS.borderLeftWidth) - - parseInt(elCSS.borderRightWidth), - child1 = _getChild(el, 0, options), - child2 = _getChild(el, 1, options), - firstChildCSS = child1 && _css(child1), - secondChildCSS = child2 && _css(child2), - firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + _getRect(child1).width, - secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + _getRect(child2).width; - - if (elCSS.display === 'flex') { - return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' - ? 'vertical' : 'horizontal'; - } - - if (elCSS.display === 'grid') { - return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; - } - - if (child1 && firstChildCSS.float !== 'none') { - var touchingSideChild2 = firstChildCSS.float === 'left' ? 'left' : 'right'; - - return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? - 'vertical' : 'horizontal'; - } - - return (child1 && - ( - firstChildCSS.display === 'block' || - firstChildCSS.display === 'flex' || - firstChildCSS.display === 'table' || - firstChildCSS.display === 'grid' || - firstChildWidth >= elWidth && - elCSS[CSSFloatProperty] === 'none' || - child2 && - elCSS[CSSFloatProperty] === 'none' && - firstChildWidth + secondChildWidth > elWidth - ) ? - 'vertical' : 'horizontal' - ); - }, - - /** - * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. - * @param {Number} x X position - * @param {Number} y Y position - * @return {HTMLElement} Element of the first found nearest Sortable - */ - _detectNearestEmptySortable = function(x, y) { - for (var i = 0; i < sortables.length; i++) { - if (_lastChild(sortables[i])) continue; - - var rect = _getRect(sortables[i]), - threshold = sortables[i][expando].options.emptyInsertThreshold, - insideHorizontally = x >= (rect.left - threshold) && x <= (rect.right + threshold), - insideVertically = y >= (rect.top - threshold) && y <= (rect.bottom + threshold); - - if (threshold && insideHorizontally && insideVertically) { - return sortables[i]; - } - } - }, - - _isClientInRowColumn = function(x, y, el, axis, options) { - var targetRect = _getRect(el), - targetS1Opp = axis === 'vertical' ? targetRect.left : targetRect.top, - targetS2Opp = axis === 'vertical' ? targetRect.right : targetRect.bottom, - mouseOnOppAxis = axis === 'vertical' ? x : y; - - return targetS1Opp < mouseOnOppAxis && mouseOnOppAxis < targetS2Opp; - }, - - _isElInRowColumn = function(el1, el2, axis) { - var el1Rect = el1 === dragEl && realDragElRect || _getRect(el1), - el2Rect = el2 === dragEl && realDragElRect || _getRect(el2), - el1S1Opp = axis === 'vertical' ? el1Rect.left : el1Rect.top, - el1S2Opp = axis === 'vertical' ? el1Rect.right : el1Rect.bottom, - el1OppLength = axis === 'vertical' ? el1Rect.width : el1Rect.height, - el2S1Opp = axis === 'vertical' ? el2Rect.left : el2Rect.top, - el2S2Opp = axis === 'vertical' ? el2Rect.right : el2Rect.bottom, - el2OppLength = axis === 'vertical' ? el2Rect.width : el2Rect.height; - - return ( - el1S1Opp === el2S1Opp || - el1S2Opp === el2S2Opp || - (el1S1Opp + el1OppLength / 2) === (el2S1Opp + el2OppLength / 2) - ); - }, - - _getParentAutoScrollElement = function(el, includeSelf) { - // skip to window - if (!el || !el.getBoundingClientRect) return _getWindowScrollingElement(); - - var elem = el; - var gotSelf = false; - do { - // we don't need to get elem css if it isn't even overflowing in the first place (performance) - if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { - var elemCSS = _css(elem); - if ( - elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || - elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll') - ) { - if (!elem || !elem.getBoundingClientRect || elem === document.body) return _getWindowScrollingElement(); - - if (gotSelf || includeSelf) return elem; - gotSelf = true; - } - } - /* jshint boss:true */ - } while (elem = elem.parentNode); - - return _getWindowScrollingElement(); - }, - - _getWindowScrollingElement = function() { - if (IE11OrLess) { - return document.documentElement; - } else { - return document.scrollingElement; - } - }, - - _scrollBy = function(el, x, y) { - el.scrollLeft += x; - el.scrollTop += y; - }, - - _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl, /**Boolean*/isFallback) { - // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (options.scroll) { - var _this = rootEl ? rootEl[expando] : window, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - - x = evt.clientX, - y = evt.clientY, - - winScroller = _getWindowScrollingElement(), - - scrollThisInstance = false; - - // Detect scrollEl - if (scrollParentEl !== rootEl) { - _clearAutoScrolls(); - - scrollEl = options.scroll; - scrollCustomFn = options.scrollFn; - - if (scrollEl === true) { - scrollEl = _getParentAutoScrollElement(rootEl, true); - scrollParentEl = scrollEl; - } - } - - - var layersOut = 0; - var currentParent = scrollEl; - do { - var el = currentParent, - rect = _getRect(el), - - top = rect.top, - bottom = rect.bottom, - left = rect.left, - right = rect.right, - - width = rect.width, - height = rect.height, - - scrollWidth, - scrollHeight, - - css, - - vx, - vy, - - canScrollX, - canScrollY, - - scrollPosX, - scrollPosY; - - - scrollWidth = el.scrollWidth; - scrollHeight = el.scrollHeight; - - css = _css(el); - - scrollPosX = el.scrollLeft; - scrollPosY = el.scrollTop; - - if (el === winScroller) { - canScrollX = width < scrollWidth && (css.overflowX === 'auto' || css.overflowX === 'scroll' || css.overflowX === 'visible'); - canScrollY = height < scrollHeight && (css.overflowY === 'auto' || css.overflowY === 'scroll' || css.overflowY === 'visible'); - } else { - canScrollX = width < scrollWidth && (css.overflowX === 'auto' || css.overflowX === 'scroll'); - canScrollY = height < scrollHeight && (css.overflowY === 'auto' || css.overflowY === 'scroll'); - } - - vx = canScrollX && (abs(right - x) <= sens && (scrollPosX + width) < scrollWidth) - (abs(left - x) <= sens && !!scrollPosX); - - vy = canScrollY && (abs(bottom - y) <= sens && (scrollPosY + height) < scrollHeight) - (abs(top - y) <= sens && !!scrollPosY); - - - if (!autoScrolls[layersOut]) { - for (var i = 0; i <= layersOut; i++) { - if (!autoScrolls[i]) { - autoScrolls[i] = {}; - } - } - } - - if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { - autoScrolls[layersOut].el = el; - autoScrolls[layersOut].vx = vx; - autoScrolls[layersOut].vy = vy; - - clearInterval(autoScrolls[layersOut].pid); - - if (el && (vx != 0 || vy != 0)) { - scrollThisInstance = true; - /* jshint loopfunc:true */ - autoScrolls[layersOut].pid = setInterval((function () { - // emulate drag over during autoscroll (fallback), emulating native DnD behaviour - if (isFallback && this.layer === 0) { - Sortable.active._emulateDragOver(true); - Sortable.active._onTouchMove(touchEvt, true); - } - var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; - var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; - - if ('function' === typeof(scrollCustomFn)) { - if (scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt, touchEvt, autoScrolls[this.layer].el) !== 'continue') { - return; - } - } - - _scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); - }).bind({layer: layersOut}), 24); - } - } - layersOut++; - } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = _getParentAutoScrollElement(currentParent, false))); - scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not - } - }, 30), - - _clearAutoScrolls = function () { - autoScrolls.forEach(function(autoScroll) { - clearInterval(autoScroll.pid); - }); - autoScrolls = []; - }, - - _prepareGroup = function (options) { - function toFn(value, pull) { - return function(to, from, dragEl, evt) { - var sameGroup = to.options.group.name && - from.options.group.name && - to.options.group.name === from.options.group.name; - - if (value == null && (pull || sameGroup)) { - // Default pull value - // Default pull and put value if same group - return true; - } else if (value == null || value === false) { - return false; - } else if (pull && value === 'clone') { - return value; - } else if (typeof value === 'function') { - return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); - } else { - var otherGroup = (pull ? to : from).options.group.name; - - return (value === true || - (typeof value === 'string' && value === otherGroup) || - (value.join && value.indexOf(otherGroup) > -1)); - } - }; - } - - var group = {}; - var originalGroup = options.group; - - if (!originalGroup || typeof originalGroup != 'object') { - originalGroup = {name: originalGroup}; - } - - group.name = originalGroup.name; - group.checkPull = toFn(originalGroup.pull, true); - group.checkPut = toFn(originalGroup.put); - group.revertClone = originalGroup.revertClone; - - options.group = group; - }, - - _checkAlignment = function(evt) { - if (!dragEl || !dragEl.parentNode) return; - dragEl.parentNode[expando] && dragEl.parentNode[expando]._computeIsAligned(evt); - }, - - _hideGhostForTarget = function() { - if (!supportCssPointerEvents && ghostEl) { - _css(ghostEl, 'display', 'none'); - } - }, - - _unhideGhostForTarget = function() { - if (!supportCssPointerEvents && ghostEl) { - _css(ghostEl, 'display', ''); - } - }; - - - // #1184 fix - Prevent click event on fallback if dragged but item not changed position - document.addEventListener('click', function(evt) { - if (ignoreNextClick) { - evt.preventDefault(); - evt.stopPropagation && evt.stopPropagation(); - evt.stopImmediatePropagation && evt.stopImmediatePropagation(); - ignoreNextClick = false; - return false; - } - }, true); - - var nearestEmptyInsertDetectEvent = function(evt) { - if (dragEl) { - evt = evt.touches ? evt.touches[0] : evt; - var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); - - if (nearest) { - // Create imitation event - var event = {}; - for (var i in evt) { - event[i] = evt[i]; - } - event.target = event.rootEl = nearest; - event.preventDefault = void 0; - event.stopPropagation = void 0; - nearest[expando]._onDragOver(event); - } - } - }; - - /** - * @class Sortable - * @param {HTMLElement} el - * @param {Object} [options] - */ - function Sortable(el, options) { - if (!(el && el.nodeType && el.nodeType === 1)) { - throw 'Sortable: `el` must be HTMLElement, not ' + {}.toString.call(el); - } - - this.el = el; // root element - this.options = options = _extend({}, options); - - - // Export instance - el[expando] = this; - - // Default options - var defaults = { - group: null, - sort: true, - disabled: false, - store: null, - handle: null, - scroll: true, - scrollSensitivity: 30, - scrollSpeed: 10, - bubbleScroll: true, - draggable: /[uo]l/i.test(el.nodeName) ? '>li' : '>*', - swapThreshold: 1, // percentage; 0 <= x <= 1 - invertSwap: false, // invert always - invertedSwapThreshold: null, // will be set to same as swapThreshold if default - removeCloneOnHide: true, - direction: function() { - return _detectDirection(el, this.options); - }, - ghostClass: 'sortable-ghost', - chosenClass: 'sortable-chosen', - dragClass: 'sortable-drag', - ignore: 'a, img', - filter: null, - preventOnFilter: true, - animation: 0, - easing: null, - setData: function (dataTransfer, dragEl) { - dataTransfer.setData('Text', dragEl.textContent); - }, - dropBubble: false, - dragoverBubble: false, - dataIdAttr: 'data-id', - delay: 0, - delayOnTouchOnly: false, - touchStartThreshold: parseInt(window.devicePixelRatio, 10) || 1, - forceFallback: false, - fallbackClass: 'sortable-fallback', - fallbackOnBody: false, - fallbackTolerance: 0, - fallbackOffset: {x: 0, y: 0}, - supportPointer: Sortable.supportPointer !== false && ('PointerEvent' in window), - emptyInsertThreshold: 5 - }; - - - // Set default options - for (var name in defaults) { - !(name in options) && (options[name] = defaults[name]); - } - - _prepareGroup(options); - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - - // Setup drag mode - this.nativeDraggable = options.forceFallback ? false : supportDraggable; - - if (this.nativeDraggable) { - // Touch start threshold cannot be greater than the native dragstart threshold - this.options.touchStartThreshold = 1; - } - - // Bind events - if (options.supportPointer) { - _on(el, 'pointerdown', this._onTapStart); - } else { - _on(el, 'mousedown', this._onTapStart); - _on(el, 'touchstart', this._onTapStart); - } - - if (this.nativeDraggable) { - _on(el, 'dragover', this); - _on(el, 'dragenter', this); - } - - sortables.push(this.el); - - // Restore sorting - options.store && options.store.get && this.sort(options.store.get(this) || []); - } - - Sortable.prototype = /** @lends Sortable.prototype */ { - constructor: Sortable, - - _computeIsAligned: function(evt) { - var target; - - if (ghostEl && !supportCssPointerEvents) { - _hideGhostForTarget(); - target = document.elementFromPoint(evt.clientX, evt.clientY); - _unhideGhostForTarget(); - } else { - target = evt.target; - } - - target = _closest(target, this.options.draggable, this.el, false); - if (_alignedSilent) return; - if (!dragEl || dragEl.parentNode !== this.el) return; - - var children = this.el.children; - for (var i = 0; i < children.length; i++) { - // Don't change for target in case it is changed to aligned before onDragOver is fired - if (_closest(children[i], this.options.draggable, this.el, false) && children[i] !== target) { - children[i].sortableMouseAligned = _isClientInRowColumn(evt.clientX, evt.clientY, children[i], this._getDirection(evt, null), this.options); - } - } - // Used for nulling last target when not in element, nothing to do with checking if aligned - if (!_closest(target, this.options.draggable, this.el, true)) { - lastTarget = null; - } - - _alignedSilent = true; - setTimeout(function() { - _alignedSilent = false; - }, 30); - - }, - - _getDirection: function(evt, target) { - return (typeof this.options.direction === 'function') ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; - }, - - _onTapStart: function (/** Event|TouchEvent */evt) { - if (!evt.cancelable) return; - var _this = this, - el = this.el, - options = this.options, - preventOnFilter = options.preventOnFilter, - type = evt.type, - touch = evt.touches && evt.touches[0], - target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && ((evt.path && evt.path[0]) || (evt.composedPath && evt.composedPath()[0])) || target, - filter = options.filter, - startIndex, - startDraggableIndex; - - _saveInputCheckedState(el); - - // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. - if (dragEl) { - return; - } - - if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { - return; // only left button and enabled - } - - // cancel dnd if original target is content editable - if (originalTarget.isContentEditable) { - return; - } - - target = _closest(target, options.draggable, el, false); - - - if (lastDownEl === target) { - // Ignoring duplicate `down` - return; - } - - // Get the index of the dragged element within its parent - startIndex = _index(target); - startDraggableIndex = _index(target, options.draggable); - - // Check filter - if (typeof filter === 'function') { - if (filter.call(this, evt, target, this)) { - _dispatchEvent(_this, originalTarget, 'filter', target, el, el, startIndex, undefined, startDraggableIndex); - preventOnFilter && evt.cancelable && evt.preventDefault(); - return; // cancel dnd - } - } - else if (filter) { - filter = filter.split(',').some(function (criteria) { - criteria = _closest(originalTarget, criteria.trim(), el, false); - - if (criteria) { - _dispatchEvent(_this, criteria, 'filter', target, el, el, startIndex, undefined, startDraggableIndex); - return true; - } - }); - - if (filter) { - preventOnFilter && evt.cancelable && evt.preventDefault(); - return; // cancel dnd - } - } - - if (options.handle && !_closest(originalTarget, options.handle, el, false)) { - return; - } - - // Prepare `dragstart` - this._prepareDragStart(evt, touch, target, startIndex, startDraggableIndex); - }, - - - _handleAutoScroll: function(evt, fallback) { - if (!dragEl || !this.options.scroll) return; - var x = evt.clientX, - y = evt.clientY, - - elem = document.elementFromPoint(x, y), - _this = this; - - // IE does not seem to have native autoscroll, - // Edge's autoscroll seems too conditional, - // MACOS Safari does not have autoscroll, - // Firefox and Chrome are good - if (fallback || Edge || IE11OrLess || Safari) { - _autoScroll(evt, _this.options, elem, fallback); - - // Listener for pointer element change - var ogElemScroller = _getParentAutoScrollElement(elem, true); - if ( - scrolling && - ( - !pointerElemChangedInterval || - x !== lastPointerElemX || - y !== lastPointerElemY - ) - ) { - - pointerElemChangedInterval && clearInterval(pointerElemChangedInterval); - // Detect for pointer elem change, emulating native DnD behaviour - pointerElemChangedInterval = setInterval(function() { - if (!dragEl) return; - // could also check if scroll direction on newElem changes due to parent autoscrolling - var newElem = _getParentAutoScrollElement(document.elementFromPoint(x, y), true); - if (newElem !== ogElemScroller) { - ogElemScroller = newElem; - _clearAutoScrolls(); - _autoScroll(evt, _this.options, ogElemScroller, fallback); - } - }, 10); - lastPointerElemX = x; - lastPointerElemY = y; - } - - } else { - // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll - if (!_this.options.bubbleScroll || _getParentAutoScrollElement(elem, true) === _getWindowScrollingElement()) { - _clearAutoScrolls(); - return; - } - _autoScroll(evt, _this.options, _getParentAutoScrollElement(elem, false), false); - } - }, - - _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex, /** Number */startDraggableIndex) { - var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - - if (target && !dragEl && (target.parentNode === el)) { - rootEl = el; - dragEl = target; - parentEl = dragEl.parentNode; - nextEl = dragEl.nextSibling; - lastDownEl = target; - activeGroup = options.group; - oldIndex = startIndex; - oldDraggableIndex = startDraggableIndex; - - tapEvt = { - target: dragEl, - clientX: (touch || evt).clientX, - clientY: (touch || evt).clientY - }; - - this._lastX = (touch || evt).clientX; - this._lastY = (touch || evt).clientY; - - dragEl.style['will-change'] = 'all'; - // undo animation if needed - dragEl.style.transition = ''; - dragEl.style.transform = ''; - - dragStartFn = function () { - // Delayed drag has been triggered - // we can re-enable the events: touchmove/mousemove - _this._disableDelayedDragEvents(); - - if (!FireFox && _this.nativeDraggable) { - dragEl.draggable = true; - } - - // Bind the events: dragstart/dragend - _this._triggerDragStart(evt, touch); - - // Drag start event - _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, rootEl, oldIndex, undefined, oldDraggableIndex); - - // Chosen item - _toggleClass(dragEl, options.chosenClass, true); - }; - - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - _find(dragEl, criteria.trim(), _disableDraggable); - }); - - _on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); - _on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); - _on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); - - _on(ownerDocument, 'mouseup', _this._onDrop); - _on(ownerDocument, 'touchend', _this._onDrop); - _on(ownerDocument, 'touchcancel', _this._onDrop); - - // Make dragEl draggable (must be before delay for FireFox) - if (FireFox && this.nativeDraggable) { - this.options.touchStartThreshold = 4; - dragEl.draggable = true; - } - - // Delay is impossible for native DnD in Edge or IE - if (options.delay && (options.delayOnTouchOnly ? touch : true) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { - // If the user moves the pointer or let go the click or touch - // before the delay has been reached: - // disable the delayed drag - _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - _on(ownerDocument, 'touchend', _this._disableDelayedDrag); - _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - _on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); - _on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); - options.supportPointer && _on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); - - _this._dragStartTimer = setTimeout(dragStartFn, options.delay); - } else { - dragStartFn(); - } - } - }, - - _delayedDragTouchMoveHandler: function (/** TouchEvent|PointerEvent **/e) { - var touch = e.touches ? e.touches[0] : e; - if (max(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) - >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1)) - ) { - this._disableDelayedDrag(); - } - }, - - _disableDelayedDrag: function () { - dragEl && _disableDraggable(dragEl); - clearTimeout(this._dragStartTimer); - - this._disableDelayedDragEvents(); - }, - - _disableDelayedDragEvents: function () { - var ownerDocument = this.el.ownerDocument; - _off(ownerDocument, 'mouseup', this._disableDelayedDrag); - _off(ownerDocument, 'touchend', this._disableDelayedDrag); - _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - _off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); - _off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); - _off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); - }, - - _triggerDragStart: function (/** Event */evt, /** Touch */touch) { - touch = touch || (evt.pointerType == 'touch' ? evt : null); - - if (!this.nativeDraggable || touch) { - if (this.options.supportPointer) { - _on(document, 'pointermove', this._onTouchMove); - } else if (touch) { - _on(document, 'touchmove', this._onTouchMove); - } else { - _on(document, 'mousemove', this._onTouchMove); - } - } else { - _on(dragEl, 'dragend', this); - _on(rootEl, 'dragstart', this._onDragStart); - } - - try { - if (document.selection) { - // Timeout neccessary for IE9 - _nextTick(function () { - document.selection.empty(); - }); - } else { - window.getSelection().removeAllRanges(); - } - } catch (err) { - } - }, - - _dragStarted: function (fallback, evt) { - awaitingDragStarted = false; - if (rootEl && dragEl) { - if (this.nativeDraggable) { - _on(document, 'dragover', this._handleAutoScroll); - _on(document, 'dragover', _checkAlignment); - } - var options = this.options; - - // Apply effect - !fallback && _toggleClass(dragEl, options.dragClass, false); - _toggleClass(dragEl, options.ghostClass, true); - - // In case dragging an animated element - _css(dragEl, 'transform', ''); - - Sortable.active = this; - - fallback && this._appendGhost(); - - // Drag start event - _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, rootEl, oldIndex, undefined, oldDraggableIndex, undefined, evt); - } else { - this._nulling(); - } - }, - - _emulateDragOver: function (forAutoScroll) { - if (touchEvt) { - if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY && !forAutoScroll) { - return; - } - this._lastX = touchEvt.clientX; - this._lastY = touchEvt.clientY; - - _hideGhostForTarget(); - - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - var parent = target; - - while (target && target.shadowRoot) { - target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); - if (target === parent) break; - parent = target; - } - - if (parent) { - do { - if (parent[expando]) { - var inserted; - - inserted = parent[expando]._onDragOver({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - - if (inserted && !this.options.dragoverBubble) { - break; - } - } - - target = parent; // store last element - } - /* jshint boss:true */ - while (parent = parent.parentNode); - } - dragEl.parentNode[expando]._computeIsAligned(touchEvt); - - _unhideGhostForTarget(); - } - }, - - - _onTouchMove: function (/**TouchEvent*/evt, forAutoScroll) { - if (tapEvt) { - var options = this.options, - fallbackTolerance = options.fallbackTolerance, - fallbackOffset = options.fallbackOffset, - touch = evt.touches ? evt.touches[0] : evt, - matrix = ghostEl && _matrix(ghostEl), - scaleX = ghostEl && matrix && matrix.a, - scaleY = ghostEl && matrix && matrix.d, - relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && _getRelativeScrollOffset(ghostRelativeParent), - dx = ((touch.clientX - tapEvt.clientX) - + fallbackOffset.x) / (scaleX || 1) - + (relativeScrollOffset ? (relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0]) : 0) / (scaleX || 1), - dy = ((touch.clientY - tapEvt.clientY) - + fallbackOffset.y) / (scaleY || 1) - + (relativeScrollOffset ? (relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1]) : 0) / (scaleY || 1), - translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; - - // only set the status to dragging, when we are actually dragging - if (!Sortable.active && !awaitingDragStarted) { - if (fallbackTolerance && - min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance - ) { - return; - } - this._onDragStart(evt, true); - } - - !forAutoScroll && this._handleAutoScroll(touch, true); - - moved = true; - touchEvt = touch; - - _css(ghostEl, 'webkitTransform', translate3d); - _css(ghostEl, 'mozTransform', translate3d); - _css(ghostEl, 'msTransform', translate3d); - _css(ghostEl, 'transform', translate3d); - - evt.cancelable && evt.preventDefault(); - } - }, - - _appendGhost: function () { - // Bug if using scale(): https://stackoverflow.com/questions/2637058 - // Not being adjusted for - if (!ghostEl) { - var container = this.options.fallbackOnBody ? document.body : rootEl, - rect = _getRect(dragEl, true, container, !PositionGhostAbsolutely), - css = _css(dragEl), - options = this.options; - - // Position absolutely - if (PositionGhostAbsolutely) { - // Get relatively positioned parent - ghostRelativeParent = container; - - while ( - _css(ghostRelativeParent, 'position') === 'static' && - _css(ghostRelativeParent, 'transform') === 'none' && - ghostRelativeParent !== document - ) { - ghostRelativeParent = ghostRelativeParent.parentNode; - } - - if (ghostRelativeParent !== document) { - var ghostRelativeParentRect = _getRect(ghostRelativeParent, true); - - rect.top -= ghostRelativeParentRect.top; - rect.left -= ghostRelativeParentRect.left; - } - - if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { - if (ghostRelativeParent === document) ghostRelativeParent = _getWindowScrollingElement(); - - rect.top += ghostRelativeParent.scrollTop; - rect.left += ghostRelativeParent.scrollLeft; - } else { - ghostRelativeParent = _getWindowScrollingElement(); - } - ghostRelativeParentInitialScroll = _getRelativeScrollOffset(ghostRelativeParent); - } - - - ghostEl = dragEl.cloneNode(true); - - _toggleClass(ghostEl, options.ghostClass, false); - _toggleClass(ghostEl, options.fallbackClass, true); - _toggleClass(ghostEl, options.dragClass, true); - - _css(ghostEl, 'box-sizing', 'border-box'); - _css(ghostEl, 'margin', 0); - _css(ghostEl, 'top', rect.top); - _css(ghostEl, 'left', rect.left); - _css(ghostEl, 'width', rect.width); - _css(ghostEl, 'height', rect.height); - _css(ghostEl, 'opacity', '0.8'); - _css(ghostEl, 'position', (PositionGhostAbsolutely ? 'absolute' : 'fixed')); - _css(ghostEl, 'zIndex', '100000'); - _css(ghostEl, 'pointerEvents', 'none'); - - container.appendChild(ghostEl); - } - }, - - _onDragStart: function (/**Event*/evt, /**boolean*/fallback) { - var _this = this; - var dataTransfer = evt.dataTransfer; - var options = _this.options; - - // Setup clone - cloneEl = _clone(dragEl); - - cloneEl.draggable = false; - cloneEl.style['will-change'] = ''; - - this._hideClone(); - - _toggleClass(cloneEl, _this.options.chosenClass, false); - - - // #1143: IFrame support workaround - _this._cloneId = _nextTick(function () { - if (!_this.options.removeCloneOnHide) { - rootEl.insertBefore(cloneEl, dragEl); - } - _dispatchEvent(_this, rootEl, 'clone', dragEl); - }); - - - !fallback && _toggleClass(dragEl, options.dragClass, true); - - // Set proper drop events - if (fallback) { - ignoreNextClick = true; - _this._loopId = setInterval(_this._emulateDragOver, 50); - } else { - // Undo what was set in _prepareDragStart before drag started - _off(document, 'mouseup', _this._onDrop); - _off(document, 'touchend', _this._onDrop); - _off(document, 'touchcancel', _this._onDrop); - - if (dataTransfer) { - dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(_this, dataTransfer, dragEl); - } - - _on(document, 'drop', _this); - - // #1276 fix: - _css(dragEl, 'transform', 'translateZ(0)'); - } - - awaitingDragStarted = true; - - _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); - _on(document, 'selectstart', _this); - if (Safari) { - _css(document.body, 'user-select', 'none'); - } - }, - - - // Returns true - if no further action is needed (either inserted or another condition) - _onDragOver: function (/**Event*/evt) { - var el = this.el, - target = evt.target, - dragRect, - targetRect, - revert, - options = this.options, - group = options.group, - activeSortable = Sortable.active, - isOwner = (activeGroup === group), - canSort = options.sort, - _this = this; - - if (_silent) return; - - // Return invocation when dragEl is inserted (or completed) - function completed(insertion) { - if (insertion) { - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(_this); - } - - if (activeSortable) { - // Set ghost class to new sortable's ghost class - _toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); - _toggleClass(dragEl, options.ghostClass, true); - } - - if (putSortable !== _this && _this !== Sortable.active) { - putSortable = _this; - } else if (_this === Sortable.active) { - putSortable = null; - } - - // Animation - dragRect && _this._animate(dragRect, dragEl); - target && targetRect && _this._animate(targetRect, target); - } - - - // Null lastTarget if it is not inside a previously swapped element - if ((target === dragEl && !dragEl.animated) || (target === el && !target.animated)) { - lastTarget = null; - } - - // no bubbling and not fallback - if (!options.dragoverBubble && !evt.rootEl && target !== document) { - _this._handleAutoScroll(evt); - dragEl.parentNode[expando]._computeIsAligned(evt); - - // Do not detect for empty insert if already inserted - !insertion && nearestEmptyInsertDetectEvent(evt); - } - - !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); - - return true; - } - - // Call when dragEl has been inserted - function changed() { - _dispatchEvent(_this, rootEl, 'change', target, el, rootEl, oldIndex, _index(dragEl), oldDraggableIndex, _index(dragEl, options.draggable), evt); - } - - - if (evt.preventDefault !== void 0) { - evt.cancelable && evt.preventDefault(); - } - - - moved = true; - - target = _closest(target, options.draggable, el, true); - - // target is dragEl or target is animated - if (dragEl.contains(evt.target) || target.animated) { - return completed(false); - } - - if (target !== dragEl) { - ignoreNextClick = false; - } - - if (activeSortable && !options.disabled && - (isOwner - ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list - : ( - putSortable === this || - ( - (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && - group.checkPut(this, activeSortable, dragEl, evt) - ) - ) - ) - ) { - var axis = this._getDirection(evt, target); - - dragRect = _getRect(dragEl); - - if (revert) { - this._hideClone(); - parentEl = rootEl; // actualization - - if (nextEl) { - rootEl.insertBefore(dragEl, nextEl); - } else { - rootEl.appendChild(dragEl); - } - - return completed(true); - } - - var elLastChild = _lastChild(el); - - if (!elLastChild || _ghostIsLast(evt, axis, el) && !elLastChild.animated) { - // assign target only if condition is true - if (elLastChild && el === evt.target) { - target = elLastChild; - } - - if (target) { - targetRect = _getRect(target); - } - - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(this); - } - - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { - el.appendChild(dragEl); - parentEl = el; // actualization - realDragElRect = null; - - changed(); - return completed(true); - } - } - else if (target && target !== dragEl && target.parentNode === el) { - var direction = 0, - targetBeforeFirstSwap, - aligned = target.sortableMouseAligned, - differentLevel = dragEl.parentNode !== el, - side1 = axis === 'vertical' ? 'top' : 'left', - scrolledPastTop = _isScrolledPast(target, 'top') || _isScrolledPast(dragEl, 'top'), - scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; - - - if (lastTarget !== target) { - lastMode = null; - targetBeforeFirstSwap = _getRect(target)[side1]; - pastFirstInvertThresh = false; - } - - // Reference: https://www.lucidchart.com/documents/view/10fa0e93-e362-4126-aca2-b709ee56bd8b/0 - if ( - _isElInRowColumn(dragEl, target, axis) && aligned || - differentLevel || - scrolledPastTop || - options.invertSwap || - lastMode === 'insert' || - // Needed, in the case that we are inside target and inserted because not aligned... aligned will stay false while inside - // and lastMode will change to 'insert', but we must swap - lastMode === 'swap' - ) { - // New target that we will be inside - if (lastMode !== 'swap') { - isCircumstantialInvert = options.invertSwap || differentLevel; - } - - direction = _getSwapDirection(evt, target, axis, - options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, - isCircumstantialInvert, - lastTarget === target); - lastMode = 'swap'; - } else { - // Insert at position - direction = _getInsertDirection(target); - lastMode = 'insert'; - } - if (direction === 0) return completed(false); - - realDragElRect = null; - lastTarget = target; - - lastDirection = direction; - - targetRect = _getRect(target); - - var nextSibling = target.nextElementSibling, - after = false; - - after = direction === 1; - - var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); - - if (moveVector !== false) { - if (moveVector === 1 || moveVector === -1) { - after = (moveVector === 1); - } - - _silent = true; - setTimeout(_unsilent, 30); - - if (isOwner) { - activeSortable._hideClone(); - } else { - activeSortable._showClone(this); - } - - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } - - // Undo chrome's scroll adjustment - if (scrolledPastTop) { - _scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); - } - - parentEl = dragEl.parentNode; // actualization - - // must be done before animation - if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { - targetMoveDistance = abs(targetBeforeFirstSwap - _getRect(target)[side1]); - } - changed(); - - return completed(true); - } - } - - if (el.contains(dragEl)) { - return completed(false); - } - } - - return false; - }, - - _animate: function (prevRect, target) { - var ms = this.options.animation; - - if (ms) { - var currentRect = _getRect(target); - - if (target === dragEl) { - realDragElRect = currentRect; - } - - if (prevRect.nodeType === 1) { - prevRect = _getRect(prevRect); - } - - // Check if actually moving position - if ((prevRect.left + prevRect.width / 2) !== (currentRect.left + currentRect.width / 2) - || (prevRect.top + prevRect.height / 2) !== (currentRect.top + currentRect.height / 2) - ) { - var matrix = _matrix(this.el), - scaleX = matrix && matrix.a, - scaleY = matrix && matrix.d; - - _css(target, 'transition', 'none'); - _css(target, 'transform', 'translate3d(' - + (prevRect.left - currentRect.left) / (scaleX ? scaleX : 1) + 'px,' - + (prevRect.top - currentRect.top) / (scaleY ? scaleY : 1) + 'px,0)' - ); - - this._repaint(target); - _css(target, 'transition', 'transform ' + ms + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); - _css(target, 'transform', 'translate3d(0,0,0)'); - } - - (typeof target.animated === 'number') && clearTimeout(target.animated); - target.animated = setTimeout(function () { - _css(target, 'transition', ''); - _css(target, 'transform', ''); - target.animated = false; - }, ms); - } - }, - - _repaint: function(target) { - return target.offsetWidth; - }, - - _offMoveEvents: function() { - _off(document, 'touchmove', this._onTouchMove); - _off(document, 'pointermove', this._onTouchMove); - _off(document, 'dragover', nearestEmptyInsertDetectEvent); - _off(document, 'mousemove', nearestEmptyInsertDetectEvent); - _off(document, 'touchmove', nearestEmptyInsertDetectEvent); - }, - - _offUpEvents: function () { - var ownerDocument = this.el.ownerDocument; - - _off(ownerDocument, 'mouseup', this._onDrop); - _off(ownerDocument, 'touchend', this._onDrop); - _off(ownerDocument, 'pointerup', this._onDrop); - _off(ownerDocument, 'touchcancel', this._onDrop); - _off(document, 'selectstart', this); - }, - - _onDrop: function (/**Event*/evt) { - var el = this.el, - options = this.options; - awaitingDragStarted = false; - scrolling = false; - isCircumstantialInvert = false; - pastFirstInvertThresh = false; - - clearInterval(this._loopId); - - clearInterval(pointerElemChangedInterval); - _clearAutoScrolls(); - _cancelThrottle(); - - clearTimeout(this._dragStartTimer); - - _cancelNextTick(this._cloneId); - _cancelNextTick(this._dragStartId); - - // Unbind events - _off(document, 'mousemove', this._onTouchMove); - - - if (this.nativeDraggable) { - _off(document, 'drop', this); - _off(el, 'dragstart', this._onDragStart); - _off(document, 'dragover', this._handleAutoScroll); - _off(document, 'dragover', _checkAlignment); - } - - if (Safari) { - _css(document.body, 'user-select', ''); - } - - this._offMoveEvents(); - this._offUpEvents(); - - if (evt) { - if (moved) { - evt.cancelable && evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); - } - - ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - - if (rootEl === parentEl || (putSortable && putSortable.lastPutMode !== 'clone')) { - // Remove clone - cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); - } - - if (dragEl) { - if (this.nativeDraggable) { - _off(dragEl, 'dragend', this); - } - - _disableDraggable(dragEl); - dragEl.style['will-change'] = ''; - - // Remove class's - _toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); - _toggleClass(dragEl, this.options.chosenClass, false); - - // Drag stop event - _dispatchEvent(this, rootEl, 'unchoose', dragEl, parentEl, rootEl, oldIndex, null, oldDraggableIndex, null, evt); - - if (rootEl !== parentEl) { - newIndex = _index(dragEl); - newDraggableIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // Add event - _dispatchEvent(null, parentEl, 'add', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - - // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - - // drag from one list and drop into another - _dispatchEvent(null, parentEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - } - - putSortable && putSortable.save(); - } - else { - if (dragEl.nextSibling !== nextEl) { - // Get the index of the dragged element within its parent - newIndex = _index(dragEl); - newDraggableIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - } - } - } - - if (Sortable.active) { - /* jshint eqnull:true */ - if (newIndex == null || newIndex === -1) { - newIndex = oldIndex; - newDraggableIndex = oldDraggableIndex; - } - _dispatchEvent(this, rootEl, 'end', dragEl, parentEl, rootEl, oldIndex, newIndex, oldDraggableIndex, newDraggableIndex, evt); - - // Save sorting - this.save(); - } - } - - } - this._nulling(); - }, - - _nulling: function() { - rootEl = - dragEl = - parentEl = - ghostEl = - nextEl = - cloneEl = - lastDownEl = - - scrollEl = - scrollParentEl = - autoScrolls.length = - - pointerElemChangedInterval = - lastPointerElemX = - lastPointerElemY = - - tapEvt = - touchEvt = - - moved = - newIndex = - oldIndex = - - lastTarget = - lastDirection = - - realDragElRect = - - putSortable = - activeGroup = - Sortable.active = null; - - savedInputChecked.forEach(function (el) { - el.checked = true; - }); - - savedInputChecked.length = 0; - }, - - handleEvent: function (/**Event*/evt) { - switch (evt.type) { - case 'drop': - case 'dragend': - this._onDrop(evt); - break; - - case 'dragenter': - case 'dragover': - if (dragEl) { - this._onDragOver(evt); - _globalDragOver(evt); - } - break; - - case 'selectstart': - evt.preventDefault(); - break; - } - }, - - - /** - * Serializes the item into an array of string. - * @returns {String[]} - */ - toArray: function () { - var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - - for (; i < n; i++) { - el = children[i]; - if (_closest(el, options.draggable, this.el, false)) { - order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); - } - } - - return order; - }, - - - /** - * Sorts the elements according to the array. - * @param {String[]} order order of the items - */ - sort: function (order) { - var items = {}, rootEl = this.el; - - this.toArray().forEach(function (id, i) { - var el = rootEl.children[i]; - - if (_closest(el, this.options.draggable, rootEl, false)) { - items[id] = el; - } - }, this); - - order.forEach(function (id) { - if (items[id]) { - rootEl.removeChild(items[id]); - rootEl.appendChild(items[id]); - } - }); - }, - - - /** - * Save the current sorting - */ - save: function () { - var store = this.options.store; - store && store.set && store.set(this); - }, - - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * @param {HTMLElement} el - * @param {String} [selector] default: `options.draggable` - * @returns {HTMLElement|null} - */ - closest: function (el, selector) { - return _closest(el, selector || this.options.draggable, this.el, false); - }, - - - /** - * Set/get option - * @param {string} name - * @param {*} [value] - * @returns {*} - */ - option: function (name, value) { - var options = this.options; - - if (value === void 0) { - return options[name]; - } else { - options[name] = value; - - if (name === 'group') { - _prepareGroup(options); - } - } - }, - - - /** - * Destroy - */ - destroy: function () { - var el = this.el; - - el[expando] = null; - - _off(el, 'mousedown', this._onTapStart); - _off(el, 'touchstart', this._onTapStart); - _off(el, 'pointerdown', this._onTapStart); - - if (this.nativeDraggable) { - _off(el, 'dragover', this); - _off(el, 'dragenter', this); - } - // Remove draggable attributes - Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { - el.removeAttribute('draggable'); - }); - - this._onDrop(); - - sortables.splice(sortables.indexOf(this.el), 1); - - this.el = el = null; - }, - - _hideClone: function() { - if (!cloneEl.cloneHidden) { - _css(cloneEl, 'display', 'none'); - cloneEl.cloneHidden = true; - if (cloneEl.parentNode && this.options.removeCloneOnHide) { - cloneEl.parentNode.removeChild(cloneEl); - } - } - }, - - _showClone: function(putSortable) { - if (putSortable.lastPutMode !== 'clone') { - this._hideClone(); - return; - } - - if (cloneEl.cloneHidden) { - // show clone at dragEl or original position - if (rootEl.contains(dragEl) && !this.options.group.revertClone) { - rootEl.insertBefore(cloneEl, dragEl); - } else if (nextEl) { - rootEl.insertBefore(cloneEl, nextEl); - } else { - rootEl.appendChild(cloneEl); - } - - if (this.options.group.revertClone) { - this._animate(dragEl, cloneEl); - } - _css(cloneEl, 'display', ''); - cloneEl.cloneHidden = false; - } - } - }; - - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { - if (el) { - ctx = ctx || document; - - do { - if ( - selector != null && - ( - selector[0] === '>' ? - el.parentNode === ctx && _matches(el, selector) : - _matches(el, selector) - ) || - includeCTX && el === ctx - ) { - return el; - } - - if (el === ctx) break; - /* jshint boss:true */ - } while (el = _getParentOrHost(el)); - } - - return null; - } - - - function _getParentOrHost(el) { - return (el.host && el !== document && el.host.nodeType) - ? el.host - : el.parentNode; - } - - - function _globalDragOver(/**Event*/evt) { - if (evt.dataTransfer) { - evt.dataTransfer.dropEffect = 'move'; - } - evt.cancelable && evt.preventDefault(); - } - - - function _on(el, event, fn) { - el.addEventListener(event, fn, IE11OrLess ? false : captureMode); - } - - - function _off(el, event, fn) { - el.removeEventListener(event, fn, IE11OrLess ? false : captureMode); - } - - - function _toggleClass(el, name, state) { - if (el && name) { - if (el.classList) { - el.classList[state ? 'add' : 'remove'](name); - } - else { - var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); - el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); - } - } - } - - - function _css(el, prop, val) { - var style = el && el.style; - - if (style) { - if (val === void 0) { - if (document.defaultView && document.defaultView.getComputedStyle) { - val = document.defaultView.getComputedStyle(el, ''); - } - else if (el.currentStyle) { - val = el.currentStyle; - } - - return prop === void 0 ? val : val[prop]; - } - else { - if (!(prop in style) && prop.indexOf('webkit') === -1) { - prop = '-webkit-' + prop; - } - - style[prop] = val + (typeof val === 'string' ? '' : 'px'); - } - } - } - - function _matrix(el) { - var appliedTransforms = ''; - do { - var transform = _css(el, 'transform'); - - if (transform && transform !== 'none') { - appliedTransforms = transform + ' ' + appliedTransforms; - } - /* jshint boss:true */ - } while (el = el.parentNode); - - if (window.DOMMatrix) { - return new DOMMatrix(appliedTransforms); - } else if (window.WebKitCSSMatrix) { - return new WebKitCSSMatrix(appliedTransforms); - } else if (window.CSSMatrix) { - return new CSSMatrix(appliedTransforms); - } - } - - - function _find(ctx, tagName, iterator) { - if (ctx) { - var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; - - if (iterator) { - for (; i < n; i++) { - iterator(list[i], i); - } - } - - return list; - } - - return []; - } - - - - function _dispatchEvent( - sortable, rootEl, name, - targetEl, toEl, fromEl, - startIndex, newIndex, - startDraggableIndex, newDraggableIndex, - originalEvt - ) { - sortable = (sortable || rootEl[expando]); - var evt, - options = sortable.options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - // Support for new CustomEvent feature - if (window.CustomEvent && !IE11OrLess && !Edge) { - evt = new CustomEvent(name, { - bubbles: true, - cancelable: true - }); - } else { - evt = document.createEvent('Event'); - evt.initEvent(name, true, true); - } - - evt.to = toEl || rootEl; - evt.from = fromEl || rootEl; - evt.item = targetEl || rootEl; - evt.clone = cloneEl; - - evt.oldIndex = startIndex; - evt.newIndex = newIndex; - - evt.oldDraggableIndex = startDraggableIndex; - evt.newDraggableIndex = newDraggableIndex; - - evt.originalEvent = originalEvt; - evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; - - if (rootEl) { - rootEl.dispatchEvent(evt); - } - - if (options[onName]) { - options[onName].call(sortable, evt); - } - } - - - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) { - var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; - // Support for new CustomEvent feature - if (window.CustomEvent && !IE11OrLess && !Edge) { - evt = new CustomEvent('move', { - bubbles: true, - cancelable: true - }); - } else { - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); - } - - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || _getRect(toEl); - evt.willInsertAfter = willInsertAfter; - - evt.originalEvent = originalEvt; - - fromEl.dispatchEvent(evt); - - if (onMoveFn) { - retVal = onMoveFn.call(sortable, evt, originalEvt); - } - - return retVal; - } - - function _disableDraggable(el) { - el.draggable = false; - } - - function _unsilent() { - _silent = false; - } - - /** - * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) - * and non-draggable elements - * @param {HTMLElement} el The parent element - * @param {Number} childNum The index of the child - * @param {Object} options Parent Sortable's options - * @return {HTMLElement} The child at index childNum, or null if not found - */ - function _getChild(el, childNum, options) { - var currentChild = 0, - i = 0, - children = el.children; - - while (i < children.length) { - if ( - children[i].style.display !== 'none' && - children[i] !== ghostEl && - children[i] !== dragEl && - _closest(children[i], options.draggable, el, false) - ) { - if (currentChild === childNum) { - return children[i]; - } - currentChild++; - } - - i++; - } - return null; - } - - /** - * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) - * @param {HTMLElement} el Parent element - * @return {HTMLElement} The last child, ignoring ghostEl - */ - function _lastChild(el) { - var last = el.lastElementChild; - - while (last && (last === ghostEl || _css(last, 'display') === 'none')) { - last = last.previousElementSibling; - } - - return last || null; - } - - function _ghostIsLast(evt, axis, el) { - var elRect = _getRect(_lastChild(el)), - mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, - mouseOnOppAxis = axis === 'vertical' ? evt.clientX : evt.clientY, - targetS2 = axis === 'vertical' ? elRect.bottom : elRect.right, - targetS1Opp = axis === 'vertical' ? elRect.left : elRect.top, - targetS2Opp = axis === 'vertical' ? elRect.right : elRect.bottom, - spacer = 10; - - return ( - axis === 'vertical' ? - (mouseOnOppAxis > targetS2Opp + spacer || mouseOnOppAxis <= targetS2Opp && mouseOnAxis > targetS2 && mouseOnOppAxis >= targetS1Opp) : - (mouseOnAxis > targetS2 && mouseOnOppAxis > targetS1Opp || mouseOnAxis <= targetS2 && mouseOnOppAxis > targetS2Opp + spacer) - ); - } - - function _getSwapDirection(evt, target, axis, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { - var targetRect = _getRect(target), - mouseOnAxis = axis === 'vertical' ? evt.clientY : evt.clientX, - targetLength = axis === 'vertical' ? targetRect.height : targetRect.width, - targetS1 = axis === 'vertical' ? targetRect.top : targetRect.left, - targetS2 = axis === 'vertical' ? targetRect.bottom : targetRect.right, - dragRect = _getRect(dragEl), - invert = false; - - - if (!invertSwap) { - // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold - if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 - // check if past first invert threshold on side opposite of lastDirection - if (!pastFirstInvertThresh && - (lastDirection === 1 ? - ( - mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 - ) : - ( - mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2 - ) - ) - ) - { - // past first invert threshold, do not restrict inverted threshold to dragEl shadow - pastFirstInvertThresh = true; - } - - if (!pastFirstInvertThresh) { - var dragS1 = axis === 'vertical' ? dragRect.top : dragRect.left, - dragS2 = axis === 'vertical' ? dragRect.bottom : dragRect.right; - // dragEl shadow (target move distance shadow) - if ( - lastDirection === 1 ? - ( - mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow - ) : - ( - mouseOnAxis > targetS2 - targetMoveDistance - ) - ) - { - return lastDirection * -1; - } - } else { - invert = true; - } - } else { - // Regular - if ( - mouseOnAxis > targetS1 + (targetLength * (1 - swapThreshold) / 2) && - mouseOnAxis < targetS2 - (targetLength * (1 - swapThreshold) / 2) - ) { - return _getInsertDirection(target); - } - } - } - - invert = invert || invertSwap; - - if (invert) { - // Invert of regular - if ( - mouseOnAxis < targetS1 + (targetLength * invertedSwapThreshold / 2) || - mouseOnAxis > targetS2 - (targetLength * invertedSwapThreshold / 2) - ) - { - return ((mouseOnAxis > targetS1 + targetLength / 2) ? 1 : -1); - } - } - - return 0; - } - - /** - * Gets the direction dragEl must be swapped relative to target in order to make it - * seem that dragEl has been "inserted" into that element's position - * @param {HTMLElement} target The target whose position dragEl is being inserted at - * @return {Number} Direction dragEl must be swapped - */ - function _getInsertDirection(target) { - var dragElIndex = _index(dragEl), - targetIndex = _index(target); - - if (dragElIndex < targetIndex) { - return 1; - } else { - return -1; - } - } - - - /** - * Generate id - * @param {HTMLElement} el - * @returns {String} - * @private - */ - function _generateId(el) { - var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - - while (i--) { - sum += str.charCodeAt(i); - } - - return sum.toString(36); - } - - /** - * Returns the index of an element within its parent for a selected set of - * elements - * @param {HTMLElement} el - * @param {selector} selector - * @return {number} - */ - function _index(el, selector) { - var index = 0; - - if (!el || !el.parentNode) { - return -1; - } - - while (el && (el = el.previousElementSibling)) { - if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && el !== cloneEl && (!selector || _matches(el, selector))) { - index++; - } - } - - return index; - } - - function _matches(/**HTMLElement*/el, /**String*/selector) { - if (!selector) return; - - selector[0] === '>' && (selector = selector.substring(1)); - - if (el) { - try { - if (el.matches) { - return el.matches(selector); - } else if (el.msMatchesSelector) { - return el.msMatchesSelector(selector); - } else if (el.webkitMatchesSelector) { - return el.webkitMatchesSelector(selector); - } - } catch(_) { - return false; - } - } - - return false; - } - - var _throttleTimeout; - function _throttle(callback, ms) { - return function () { - if (!_throttleTimeout) { - var args = arguments, - _this = this; - - _throttleTimeout = setTimeout(function () { - if (args.length === 1) { - callback.call(_this, args[0]); - } else { - callback.apply(_this, args); - } - - _throttleTimeout = void 0; - }, ms); - } - }; - } - - function _cancelThrottle() { - clearTimeout(_throttleTimeout); - _throttleTimeout = void 0; - } - - function _extend(dst, src) { - if (dst && src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - } - - return dst; - } - - function _clone(el) { - if (Polymer && Polymer.dom) { - return Polymer.dom(el).cloneNode(true); - } - else if ($) { - return $(el).clone(true)[0]; - } - else { - return el.cloneNode(true); - } - } - - function _saveInputCheckedState(root) { - savedInputChecked.length = 0; - - var inputs = root.getElementsByTagName('input'); - var idx = inputs.length; - - while (idx--) { - var el = inputs[idx]; - el.checked && savedInputChecked.push(el); - } - } - - function _nextTick(fn) { - return setTimeout(fn, 0); - } - - function _cancelNextTick(id) { - return clearTimeout(id); - } - - - /** - * Returns the "bounding client rect" of given element - * @param {HTMLElement} el The element whose boundingClientRect is wanted - * @param {[HTMLElement]} container the parent the element will be placed in - * @param {[Boolean]} adjustForTransform Whether the rect should compensate for parent's transform - * @return {Object} The boundingClientRect of el - */ - function _getRect(el, adjustForTransform, container, adjustForFixed) { - if (!el.getBoundingClientRect && el !== win) return; - - var elRect, - top, - left, - bottom, - right, - height, - width; - - if (el !== win && el !== _getWindowScrollingElement()) { - elRect = el.getBoundingClientRect(); - top = elRect.top; - left = elRect.left; - bottom = elRect.bottom; - right = elRect.right; - height = elRect.height; - width = elRect.width; - } else { - top = 0; - left = 0; - bottom = window.innerHeight; - right = window.innerWidth; - height = window.innerHeight; - width = window.innerWidth; - } - - if (adjustForFixed && el !== win) { - // Adjust for translate() - container = container || el.parentNode; - - // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) - // Not needed on <= IE11 - if (!IE11OrLess) { - do { - if (container && container.getBoundingClientRect && _css(container, 'transform') !== 'none') { - var containerRect = container.getBoundingClientRect(); - - // Set relative to edges of padding box of container - top -= containerRect.top + parseInt(_css(container, 'border-top-width')); - left -= containerRect.left + parseInt(_css(container, 'border-left-width')); - bottom = top + elRect.height; - right = left + elRect.width; - - break; - } - /* jshint boss:true */ - } while (container = container.parentNode); - } - } - - if (adjustForTransform && el !== win) { - // Adjust for scale() - var matrix = _matrix(container || el), - scaleX = matrix && matrix.a, - scaleY = matrix && matrix.d; - - if (matrix) { - top /= scaleY; - left /= scaleX; - - width /= scaleX; - height /= scaleY; - - bottom = top + height; - right = left + width; - } - } - - return { - top: top, - left: left, - bottom: bottom, - right: right, - width: width, - height: height - }; - } - - - /** - * Checks if a side of an element is scrolled past a side of it's parents - * @param {HTMLElement} el The element who's side being scrolled out of view is in question - * @param {String} side Side of the element in question ('top', 'left', 'right', 'bottom') - * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element - */ - function _isScrolledPast(el, side) { - var parent = _getParentAutoScrollElement(el, true), - elSide = _getRect(el)[side]; - - /* jshint boss:true */ - while (parent) { - var parentSide = _getRect(parent)[side], - visible; - - if (side === 'top' || side === 'left') { - visible = elSide >= parentSide; - } else { - visible = elSide <= parentSide; - } - - if (!visible) return parent; - - if (parent === _getWindowScrollingElement()) break; - - parent = _getParentAutoScrollElement(parent, false); - } - - return false; - } - - /** - * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. - * The value is returned in real pixels. - * @param {HTMLElement} el - * @return {Array} Offsets in the format of [left, top] - */ - function _getRelativeScrollOffset(el) { - var offsetLeft = 0, - offsetTop = 0, - winScroller = _getWindowScrollingElement(); - - if (el) { - do { - var matrix = _matrix(el), - scaleX = matrix.a, - scaleY = matrix.d; - - offsetLeft += el.scrollLeft * scaleX; - offsetTop += el.scrollTop * scaleY; - } while (el !== winScroller && (el = el.parentNode)); - } - - return [offsetLeft, offsetTop]; - } - - // Fixed #973: - _on(document, 'touchmove', function(evt) { - if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { - evt.preventDefault(); - } - }); - - - // Export utils - Sortable.utils = { - on: _on, - off: _off, - css: _css, - find: _find, - is: function (el, selector) { - return !!_closest(el, selector, el, false); - }, - extend: _extend, - throttle: _throttle, - closest: _closest, - toggleClass: _toggleClass, - clone: _clone, - index: _index, - nextTick: _nextTick, - cancelNextTick: _cancelNextTick, - detectDirection: _detectDirection, - getChild: _getChild - }; - - - /** - * Create sortable instance - * @param {HTMLElement} el - * @param {Object} [options] - */ - Sortable.create = function (el, options) { - return new Sortable(el, options); - }; - - - // Export - Sortable.version = '1.9.0'; - return Sortable; -}); + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { + vertical = this._getDirection(evt, target) === 'vertical'; + dragRect = getRect(dragEl); + dragOverEvent('dragOverValid'); + if (Sortable$1.eventCanceled) return completedFired; + + if (revert) { + parentEl = rootEl; // actualization + + capture(); + + this._hideClone(); + + dragOverEvent('revert'); + + if (!Sortable$1.eventCanceled) { + if (nextEl) { + rootEl.insertBefore(dragEl, nextEl); + } else { + rootEl.appendChild(dragEl); + } + } + + return completed(true); + } + + var elLastChild = lastChild(el, options.draggable); + + if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // If already at end of list: Do not insert + if (elLastChild === dragEl) { + return completed(false); + } // assign target only if condition is true + + + if (elLastChild && el === evt.target) { + target = elLastChild; + } + + if (target) { + targetRect = getRect(target); + } + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { + capture(); + el.appendChild(dragEl); + parentEl = el; // actualization + + changed(); + return completed(true); + } + } else if (target.parentNode === el) { + targetRect = getRect(target); + var direction = 0, + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, null, 'top', 'top') || isScrolledPast(dragEl, null, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; + + if (lastTarget !== target) { + targetBeforeFirstSwap = targetRect[side1]; + pastFirstInvertThresh = false; + isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; + } + + direction = _getSwapDirection(evt, target, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + var sibling; + + if (direction !== 0) { + // Check if target is beside dragEl in respective direction (ignoring hidden elements) + var dragIndex = index(dragEl); + + do { + dragIndex -= direction; + sibling = parentEl.children[dragIndex]; + } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); + } // If dragEl is already beside target: Do not insert + + + if (direction === 0 || sibling === target) { + return completed(false); + } + + lastTarget = target; + lastDirection = direction; + var nextSibling = target.nextElementSibling, + after = false; + after = direction === 1; + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = moveVector === 1; + } + + _silent = true; + setTimeout(_unsilent, 30); + capture(); + + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } // Undo chrome's scroll adjustment (has no effect on other browsers) + + + if (scrolledPastTop) { + scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); + } + + parentEl = dragEl.parentNode; // actualization + // must be done before animation + + if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { + targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); + } + + changed(); + return completed(true); + } + } + + if (el.contains(dragEl)) { + return completed(false); + } + } + + return false; + }, + _ignoreWhileAnimating: null, + _offMoveEvents: function _offMoveEvents() { + off(document, 'mousemove', this._onTouchMove); + off(document, 'touchmove', this._onTouchMove); + off(document, 'pointermove', this._onTouchMove); + off(document, 'dragover', nearestEmptyInsertDetectEvent); + off(document, 'mousemove', nearestEmptyInsertDetectEvent); + off(document, 'touchmove', nearestEmptyInsertDetectEvent); + }, + _offUpEvents: function _offUpEvents() { + var ownerDocument = this.el.ownerDocument; + off(ownerDocument, 'mouseup', this._onDrop); + off(ownerDocument, 'touchend', this._onDrop); + off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'touchcancel', this._onDrop); + off(document, 'selectstart', this); + }, + _onDrop: function _onDrop( + /**Event*/ + evt) { + var el = this.el, + options = this.options; // Get the index of the dragged element within its parent + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + pluginEvent('drop', this, { + evt: evt + }); // Get again after plugin event + + newIndex = index(dragEl); + newDraggableIndex = index(dragEl, options.draggable); + + if (Sortable$1.eventCanceled) { + this._nulling(); + + return; + } + + awaitingDragStarted = false; + isCircumstantialInvert = false; + pastFirstInvertThresh = false; + clearInterval(this._loopId); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this.cloneId); + + _cancelNextTick(this._dragStartId); // Unbind events + + + if (this.nativeDraggable) { + off(document, 'drop', this); + off(el, 'dragstart', this._onDragStart); + } + + this._offMoveEvents(); + + this._offUpEvents(); + + if (Safari) { + css(document.body, 'user-select', ''); + } + + if (evt) { + if (moved) { + evt.cancelable && evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + // Remove clone(s) + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + + dragEl.style['will-change'] = ''; // Remove classes + // ghostClass is added in dragStarted + + if (moved && !awaitingDragStarted) { + toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); + } + + toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event + + _dispatchEvent({ + sortable: this, + name: 'unchoose', + toEl: parentEl, + newIndex: null, + newDraggableIndex: null, + originalEvent: evt + }); + + if (rootEl !== parentEl) { + if (newIndex >= 0) { + // Add event + _dispatchEvent({ + rootEl: parentEl, + name: 'add', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); // Remove event + + + _dispatchEvent({ + sortable: this, + name: 'remove', + toEl: parentEl, + originalEvent: evt + }); // drag from one list and drop into another + + + _dispatchEvent({ + rootEl: parentEl, + name: 'sort', + toEl: parentEl, + fromEl: rootEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + + putSortable && putSortable.save(); + } else { + if (newIndex !== oldIndex) { + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent({ + sortable: this, + name: 'update', + toEl: parentEl, + originalEvent: evt + }); + + _dispatchEvent({ + sortable: this, + name: 'sort', + toEl: parentEl, + originalEvent: evt + }); + } + } + } + + if (Sortable$1.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + newDraggableIndex = oldDraggableIndex; + } + + _dispatchEvent({ + sortable: this, + name: 'end', + toEl: parentEl, + originalEvent: evt + }); // Save sorting + + + this.save(); + } + } + } + + this._nulling(); + }, + _nulling: function _nulling() { + pluginEvent('nulling', this); + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable$1.dragged = Sortable$1.ghost = Sortable$1.clone = Sortable$1.active = null; + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = 0; + }, + handleEvent: function handleEvent( + /**Event*/ + evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + + break; + + case 'dragenter': + case 'dragover': + if (dragEl) { + this._onDragOver(evt); + + _globalDragOver(evt); + } + + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function toArray() { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + + if (closest(el, options.draggable, this.el, false)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function sort(order) { + var items = {}, + rootEl = this.el; + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (closest(el, this.options.draggable, rootEl, false)) { + items[id] = el; + } + }, this); + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + /** + * Save the current sorting + */ + save: function save() { + var store = this.options.store; + store && store.set && store.set(this); + }, + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function closest$1(el, selector) { + return closest(el, selector || this.options.draggable, this.el, false); + }, + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function option(name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + var modifiedValue = PluginManager.modifyOption(this, name, value); + + if (typeof modifiedValue !== 'undefined') { + options[name] = modifiedValue; + } else { + options[name] = value; + } + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + /** + * Destroy + */ + destroy: function destroy() { + pluginEvent('destroy', this); + var el = this.el; + el[expando] = null; + off(el, 'mousedown', this._onTapStart); + off(el, 'touchstart', this._onTapStart); + off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + off(el, 'dragover', this); + off(el, 'dragenter', this); + } // Remove draggable attributes + + + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + this._onDrop(); + + sortables.splice(sortables.indexOf(this.el), 1); + this.el = el = null; + }, + _hideClone: function _hideClone() { + if (!cloneHidden) { + pluginEvent('hideClone', this); + if (Sortable$1.eventCanceled) return; + css(cloneEl, 'display', 'none'); + + if (this.options.removeCloneOnHide && cloneEl.parentNode) { + cloneEl.parentNode.removeChild(cloneEl); + } + + cloneHidden = true; + } + }, + _showClone: function _showClone(putSortable) { + if (putSortable.lastPutMode !== 'clone') { + this._hideClone(); + + return; + } + + if (cloneHidden) { + pluginEvent('showClone', this); + if (Sortable$1.eventCanceled) return; // show clone at dragEl or original position + + if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + rootEl.insertBefore(cloneEl, dragEl); + } else if (nextEl) { + rootEl.insertBefore(cloneEl, nextEl); + } else { + rootEl.appendChild(cloneEl); + } + + if (this.options.group.revertClone) { + this._animate(dragEl, cloneEl); + } + + css(cloneEl, 'display', ''); + cloneHidden = false; + } + } + }; + + function _globalDragOver( + /**Event*/ + evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + + evt.cancelable && evt.preventDefault(); + } + + function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; // Support for new CustomEvent feature + + if (window.CustomEvent && !IE11OrLess && !Edge) { + evt = new CustomEvent('move', { + bubbles: true, + cancelable: true + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); + } + + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || getRect(toEl); + evt.willInsertAfter = willInsertAfter; + evt.originalEvent = originalEvent; + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvent); + } + + return retVal; + } + + function _disableDraggable(el) { + el.draggable = false; + } + + function _unsilent() { + _silent = false; + } + + function _ghostIsLast(evt, vertical, sortable) { + var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var spacer = 10; + return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; + } + + function _getSwapDirection(evt, target, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var targetRect = getRect(target), + mouseOnAxis = vertical ? evt.clientY : evt.clientX, + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; + + if (!invertSwap) { + // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold + if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { + // multiplied only by swapThreshold because mouse will already be inside target by (1 - threshold) * targetLength / 2 + // check if past first invert threshold on side opposite of lastDirection + if (!pastFirstInvertThresh && (lastDirection === 1 ? mouseOnAxis > targetS1 + targetLength * invertedSwapThreshold / 2 : mouseOnAxis < targetS2 - targetLength * invertedSwapThreshold / 2)) { + // past first invert threshold, do not restrict inverted threshold to dragEl shadow + pastFirstInvertThresh = true; + } + + if (!pastFirstInvertThresh) { + // dragEl shadow (target move distance shadow) + if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow + : mouseOnAxis > targetS2 - targetMoveDistance) { + return -lastDirection; + } + } else { + invert = true; + } + } else { + // Regular + if (mouseOnAxis > targetS1 + targetLength * (1 - swapThreshold) / 2 && mouseOnAxis < targetS2 - targetLength * (1 - swapThreshold) / 2) { + return _getInsertDirection(target); + } + } + } + + invert = invert || invertSwap; + + if (invert) { + // Invert of regular + if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { + return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; + } + } + + return 0; + } + /** + * Gets the direction dragEl must be swapped relative to target in order to make it + * seem that dragEl has been "inserted" into that element's position + * @param {HTMLElement} target The target whose position dragEl is being inserted at + * @return {Number} Direction dragEl must be swapped + */ + + + function _getInsertDirection(target) { + if (index(dragEl) < index(target)) { + return 1; + } else { + return -1; + } + } + /** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + + + function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); + } + + function _saveInputCheckedState(root) { + savedInputChecked.length = 0; + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var _el = inputs[idx]; + _el.checked && savedInputChecked.push(_el); + } + } + + function _nextTick(fn) { + return setTimeout(fn, 0); + } + + function _cancelNextTick(id) { + return clearTimeout(id); + } // Fixed #973: + + + on(document, 'touchmove', function (evt) { + if ((Sortable$1.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); // Export utils + + Sortable$1.utils = { + on: on, + off: off, + css: css, + find: find, + is: function is(el, selector) { + return !!closest(el, selector, el, false); + }, + extend: extend, + throttle: throttle, + closest: closest, + toggleClass: toggleClass, + clone: clone, + index: index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick, + detectDirection: _detectDirection, + getChild: getChild + }; + /** + * Mount a plugin to Sortable + * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted + */ + + Sortable$1.mount = function () { + for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { + plugins[_key] = arguments[_key]; + } + + if (plugins[0].constructor === Array) plugins = plugins[0]; + + for (var i in plugins) { + var plugin = plugins[i]; + + if (!plugin.prototype || !plugin.prototype.constructor) { + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(el)); + } + + if (plugin.utils) Sortable$1.utils = _objectSpread({}, Sortable$1.utils, plugin.utils); + PluginManager.mount(plugin); + } + }; + /** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + + + Sortable$1.create = function (el, options) { + return new Sortable$1(el, options); + }; // Export + + + Sortable$1.version = version; + + var autoScrolls = [], + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; + + function AutoScrollPlugin() { + function AutoScroll() { + this.options = { + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + bubbleScroll: true + }; // Bind all private methods + + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + } + + AutoScroll.prototype = { + dragStarted: function dragStarted(_ref) { + var originalEvent = _ref.originalEvent; + + if (this.sortable.nativeDraggable) { + on(document, 'dragover', this._handleAutoScroll); + } else { + if (this.sortable.options.supportPointer) { + on(document, 'pointermove', this._handleFallbackAutoScroll); + } else if (originalEvent.touches) { + on(document, 'touchmove', this._handleFallbackAutoScroll); + } else { + on(document, 'mousemove', this._handleFallbackAutoScroll); + } + } + }, + dragOverCompleted: function dragOverCompleted(_ref2) { + var originalEvent = _ref2.originalEvent; + + // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) + if (!this.sortable.options.dragOverBubble && !originalEvent.rootEl) { + this._handleAutoScroll(originalEvent); + } + }, + drop: function drop() { + if (this.sortable.nativeDraggable) { + off(document, 'dragover', this._handleAutoScroll); + } else { + off(document, 'pointermove', this._handleFallbackAutoScroll); + off(document, 'touchmove', this._handleFallbackAutoScroll); + off(document, 'mousemove', this._handleFallbackAutoScroll); + } + + clearPointerElemChangedInterval(); + clearAutoScrolls(); + cancelThrottle(); + }, + nulling: function nulling() { + touchEvt$1 = scrollRootEl = scrollEl = scrolling = pointerElemChangedInterval = lastAutoScrollX = lastAutoScrollY = null; + autoScrolls.length = 0; + }, + _handleFallbackAutoScroll: function _handleFallbackAutoScroll(evt) { + this._handleAutoScroll(evt, true); + }, + _handleAutoScroll: function _handleAutoScroll(evt, fallback) { + var _this = this; + + var x = evt.clientX, + y = evt.clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; // IE does not seem to have native autoscroll, + // Edge's autoscroll seems too conditional, + // MACOS Safari does not have autoscroll, + // Firefox and Chrome are good + + if (fallback || Edge || IE11OrLess || Safari) { + autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + + var ogElemScroller = getParentAutoScrollElement(elem, true); + + if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { + pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour + + pointerElemChangedInterval = setInterval(function () { + var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); + + if (newElem !== ogElemScroller) { + ogElemScroller = newElem; + clearAutoScrolls(); + } + + autoScroll(evt, _this.options, newElem, fallback); + }, 10); + lastAutoScrollX = x; + lastAutoScrollY = y; + } + } else { + // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll + if (!this.sortable.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + clearAutoScrolls(); + return; + } + + autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); + } + } + }; + return _extends(AutoScroll, { + pluginName: 'scroll', + initializeByDefault: true + }); + } + + function clearAutoScrolls() { + autoScrolls.forEach(function (autoScroll) { + clearInterval(autoScroll.pid); + }); + autoScrolls = []; + } + + function clearPointerElemChangedInterval() { + clearInterval(pointerElemChangedInterval); + } + + var autoScroll = throttle(function (evt, options, rootEl, isFallback) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (!options.scroll) return; + var sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); + var scrollThisInstance = false, + scrollCustomFn; // New scroll root, set scrollEl + + if (scrollRootEl !== rootEl) { + scrollRootEl = rootEl; + clearAutoScrolls(); + scrollEl = options.scroll; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = getParentAutoScrollElement(rootEl, true); + } + } + + var layersOut = 0; + var currentParent = scrollEl; + + do { + var el = currentParent, + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; + + if (el === winScroller) { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); + } else { + canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); + canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); + } + + var vx = canScrollX && (Math.abs(right - evt.clientX) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - evt.clientX) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - evt.clientY) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - evt.clientY) <= sens && !!scrollPosY); + + if (!autoScrolls[layersOut]) { + for (var i = 0; i <= layersOut; i++) { + if (!autoScrolls[i]) { + autoScrolls[i] = {}; + } + } + } + + if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { + autoScrolls[layersOut].el = el; + autoScrolls[layersOut].vx = vx; + autoScrolls[layersOut].vy = vy; + clearInterval(autoScrolls[layersOut].pid); + + if (vx != 0 || vy != 0) { + scrollThisInstance = true; + /* jshint loopfunc:true */ + + autoScrolls[layersOut].pid = setInterval(function () { + // emulate drag over during autoscroll (fallback), emulating native DnD behaviour + if (isFallback && this.layer === 0) { + Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely + + } + + var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; + var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; + + if (typeof scrollCustomFn === 'function') { + if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { + return; + } + } + + scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); + }.bind({ + layer: layersOut + }), 24); + } + } + + layersOut++; + } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); + + scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not + }, 30); + + var drop = function drop(_ref) { + var originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; + var toSortable = putSortable || activeSortable; + hideGhostForTarget(); + var target = document.elementFromPoint(originalEvent.clientX, originalEvent.clientY); + unhideGhostForTarget(); + + if (toSortable && !toSortable.el.contains(target)) { + dispatchSortableEvent('spill'); + this.onSpill(dragEl); + } + }; + + function Revert() {} + + Revert.prototype = { + startIndex: null, + dragStart: function dragStart(_ref2) { + var oldDraggableIndex = _ref2.oldDraggableIndex; + this.startIndex = oldDraggableIndex; + }, + onSpill: function onSpill(dragEl) { + this.sortable.captureAnimationState(); + var nextSibling = getChild(this.sortable.el, this.startIndex, this.sortable.options); + + if (nextSibling) { + this.sortable.el.insertBefore(dragEl, nextSibling); + } else { + this.sortable.el.appendChild(dragEl); + } + + this.sortable.animateAll(); + }, + drop: drop + }; + + _extends(Revert, { + pluginName: 'revertOnSpill' + }); + + function Remove() {} + + Remove.prototype = { + onSpill: function onSpill(dragEl) { + this.sortable.captureAnimationState(); + dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); + this.sortable.animateAll(); + }, + drop: drop + }; + + _extends(Remove, { + pluginName: 'removeOnSpill' + }); + + var lastSwapEl; + + function SwapPlugin() { + function Swap() { + this.options = { + swapClass: 'sortable-swap-highlight' + }; + } + + Swap.prototype = { + dragStart: function dragStart(_ref) { + var dragEl = _ref.dragEl; + lastSwapEl = dragEl; + }, + dragOverValid: function dragOverValid(_ref2) { + var completed = _ref2.completed, + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed; + if (!activeSortable.options.swap) return; + var el = this.sortable.el, + options = this.sortable.options; + + if (target && target !== el) { + var prevSwapEl = lastSwapEl; + + if (onMove(target) !== false) { + toggleClass(target, options.swapClass, true); + lastSwapEl = target; + } else { + lastSwapEl = null; + } + + if (prevSwapEl && prevSwapEl !== lastSwapEl) { + toggleClass(prevSwapEl, options.swapClass, false); + } + } + + changed(); + return completed(true); + }, + drop: function drop(_ref3) { + var activeSortable = _ref3.activeSortable, + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; + var toSortable = putSortable || this.sortable; + var options = this.sortable.options; + lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); + + if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { + if (dragEl !== lastSwapEl) { + toSortable.captureAnimationState(); + if (toSortable !== activeSortable) activeSortable.captureAnimationState(); + swapNodes(dragEl, lastSwapEl); + toSortable.animateAll(); + if (toSortable !== activeSortable) activeSortable.animateAll(); + } + } + }, + nulling: function nulling() { + lastSwapEl = null; + } + }; + return _extends(Swap, { + pluginName: 'swap', + eventOptions: function eventOptions() { + return { + swapItem: lastSwapEl + }; + } + }); + } + + function swapNodes(n1, n2) { + var p1 = n1.parentNode, + p2 = n2.parentNode, + i1, + i2; + if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; + i1 = index(n1); + i2 = index(n2); + + if (p1.isEqualNode(p2) && i1 < i2) { + i2++; + } + + p1.insertBefore(n2, p1.children[i1]); + p2.insertBefore(n1, p2.children[i2]); + } + + var multiDragElements = [], + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) + multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started + folding = false, + // Folding any other time + dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; + + function MultiDragPlugin() { + function MultiDrag(sortable) { + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } + + on(document, 'keydown', this._checkKeyDown); + on(document, 'keyup', this._checkKeyUp); + this.options = { + selectedClass: 'sortable-selected', + multiDragKey: null, + setData: function setData(dataTransfer, dragEl) { + var data = ''; + + if (multiDragElements.length && multiDragSortable === sortable) { + for (var i in multiDragElements) { + data += (!i ? '' : ', ') + multiDragElements[i].textContent; + } + } else { + data = dragEl.textContent; + } + + dataTransfer.setData('Text', data); + } + }; + } + + MultiDrag.prototype = { + multiDragKeyDown: false, + isMultiDrag: false, + delayStartGlobal: function delayStartGlobal(_ref) { + var dragged = _ref.dragEl; + dragEl$1 = dragged; + }, + delayEnded: function delayEnded() { + this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); + }, + setupClone: function setupClone(_ref2) { + var sortable = _ref2.sortable; + if (!this.isMultiDrag) return; + + for (var i in multiDragElements) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], sortable.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], sortable.options.chosenClass, false); + } + + sortable._hideClone(); + + return true; + }, + clone: function clone(_ref3) { + var sortable = _ref3.sortable, + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent; + if (!this.isMultiDrag) return; + + if (!sortable.options.removeCloneOnHide) { + if (multiDragElements.length && multiDragSortable === sortable) { + insertMultiDragClones(true, rootEl); + dispatchSortableEvent('clone'); + return true; + } + } + }, + showClone: function showClone(_ref4) { + var cloneNowShown = _ref4.cloneNowShown, + rootEl = _ref4.rootEl; + if (!this.isMultiDrag) return; + insertMultiDragClones(false, rootEl); + + for (var i in multiDragClones) { + css(multiDragClones[i], 'display', ''); + } + + cloneNowShown(); + clonesHidden = false; + return true; + }, + hideClone: function hideClone(_ref5) { + var sortable = _ref5.sortable, + cloneNowHidden = _ref5.cloneNowHidden; + if (!this.isMultiDrag) return; + + for (var i in multiDragClones) { + css(multiDragClones[i], 'display', 'none'); + + if (sortable.options.removeCloneOnHide && multiDragClones[i].parentNode) { + multiDragClones[i].parentNode.removeChild(multiDragClones[i]); + } + } + + cloneNowHidden(); + clonesHidden = true; + return true; + }, + dragStartGlobal: function dragStartGlobal(_ref6) { + var sortable = _ref6.sortable; + + if (!this.isMultiDrag && multiDragSortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + } + + for (var i in multiDragElements) { + multiDragElements[i].sortableIndex = index(multiDragElements[i]); + } // Sort multi-drag elements + + + multiDragElements = multiDragElements.sort(function (a, b) { + return a.sortableIndex - b.sortableIndex; + }); + dragStarted = true; + }, + dragStarted: function dragStarted(_ref7) { + var sortable = _ref7.sortable; + if (!this.isMultiDrag) return; + + if (sortable.options.sort) { + // Capture rects, + // hide multi drag elements (by positioning them absolute), + // set multi drag elements rects to dragRect, + // show multi drag elements, + // animate to rects, + // unset rects & remove from DOM + sortable.captureAnimationState(); + + if (sortable.options.animation) { + for (var i in multiDragElements) { + if (multiDragElements[i] === dragEl$1) continue; + css(multiDragElements[i], 'position', 'absolute'); + } + + var dragRect = getRect(dragEl$1, false, true, true); + + for (var _i in multiDragElements) { + if (multiDragElements[_i] === dragEl$1) continue; + setRect(multiDragElements[_i], dragRect); + } + + folding = true; + initialFolding = true; + } + } + + sortable.animateAll(function () { + folding = false; + initialFolding = false; + + if (sortable.options.animation) { + for (var _i2 in multiDragElements) { + unsetRect(multiDragElements[_i2]); + } + } // Remove all auxiliary multidrag items from el, if sorting enabled + + + if (sortable.options.sort) { + removeMultiDragElements(); + } + }); + }, + dragOver: function dragOver(_ref8) { + var target = _ref8.target, + completed = _ref8.completed; + + if (folding && ~multiDragElements.indexOf(target)) { + return completed(false); + } + }, + revert: function revert(_ref9) { + var fromSortable = _ref9.fromSortable, + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; + + if (multiDragElements.length > 1) { + // Setup unfold animation + for (var i in multiDragElements) { + sortable.addAnimationState({ + target: multiDragElements[i], + rect: folding ? getRect(multiDragElements[i]) : dragRect + }); + unsetRect(multiDragElements[i]); + multiDragElements[i].fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElements[i]); + } + + folding = false; + insertMultiDragElements(!sortable.options.removeCloneOnHide, rootEl); + } + }, + dragOverCompleted: function dragOverCompleted(_ref10) { + var sortable = _ref10.sortable, + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; + var options = sortable.options; + + if (insertion) { + // Clones must be hidden before folding animation to capture dragRectAbsolute properly + if (isOwner) { + activeSortable._hideClone(); + } + + initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location + + if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { + // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible + var dragRectAbsolute = getRect(dragEl$1, false, true, true); + + for (var i in multiDragElements) { + if (multiDragElements[i] === dragEl$1) continue; + setRect(multiDragElements[i], dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + + parentEl.appendChild(multiDragElements[i]); + } + + folding = true; + } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out + + + if (!isOwner) { + // Only remove if not folding (folding will remove them anyways) + if (!folding) { + removeMultiDragElements(); + } + + if (multiDragElements.length > 1) { + var clonesHiddenBefore = clonesHidden; + + activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden + + + if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { + for (var _i3 in multiDragClones) { + activeSortable.addAnimationState({ + target: multiDragClones[_i3], + rect: clonesFromRect + }); + multiDragClones[_i3].fromRect = clonesFromRect; + multiDragClones[_i3].thisAnimationDuration = null; + } + } + } else { + activeSortable._showClone(sortable); + } + } + } + }, + dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { + var dragRect = _ref11.dragRect, + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; + + for (var i in multiDragElements) { + multiDragElements[i].thisAnimationDuration = null; + } + + if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { + clonesFromRect = _extends({}, dragRect); + var dragMatrix = matrix(dragEl$1, true); + clonesFromRect.top -= dragMatrix.f; + clonesFromRect.left -= dragMatrix.e; + } + }, + dragOverAnimationComplete: function dragOverAnimationComplete() { + if (folding) { + folding = false; + removeMultiDragElements(); + } + }, + drop: function drop(_ref12) { + var evt = _ref12.originalEvent, + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; + var toSortable = putSortable || this.sortable; + if (!evt) return; + var options = sortable.options, + children = parentEl.children; // Multi-drag selection + + if (!dragStarted) { + if (options.multiDragKey && !this.multiDragKeyDown) { + this._deselectMultiDrag(); + } + + toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); + + if (!~multiDragElements.indexOf(dragEl$1)) { + multiDragElements.push(dragEl$1); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: dragEl$1, + originalEvt: evt + }); // Modifier activated, select from last to dragEl + + if ((!options.multiDragKey || this.multiDragKeyDown) && evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + var lastIndex = index(lastMultiDragSelect), + currentIndex = index(dragEl$1); + + if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvt: evt + }); + } + } + } else { + lastMultiDragSelect = dragEl$1; + } + + multiDragSortable = toSortable; + } else { + multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); + lastMultiDragSelect = null; + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'deselect', + targetEl: dragEl$1, + originalEvt: evt + }); + } + } // Multi-drag drop + + + if (dragStarted && this.isMultiDrag) { + // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { + var dragRect = getRect(dragEl$1), + multiDragIndex = index(dragEl$1, ':not(.' + Sortable.active.options.selectedClass + ')'); + if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; + toSortable.captureAnimationState(); + + if (!initialFolding) { + if (options.animation) { + dragEl$1.fromRect = dragRect; + + for (var _i4 in multiDragElements) { + multiDragElements[_i4].thisAnimationDuration = null; + + if (multiDragElements[_i4] !== dragEl$1) { + var rect = folding ? getRect(multiDragElements[_i4]) : dragRect; + multiDragElements[_i4].fromRect = rect; // Prepare unfold animation + + toSortable.addAnimationState({ + target: multiDragElements[_i4], + rect: rect + }); + } + } + } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed + + + removeMultiDragElements(); + + for (var _i5 in multiDragElements) { + if (children[multiDragIndex]) { + parentEl.insertBefore(multiDragElements[_i5], children[multiDragIndex]); + } else { + parentEl.appendChild(multiDragElements[_i5]); + } + + multiDragIndex++; + } // If initial folding is done, the elements may have changed position because they are now + // unfolding around dragEl, even though dragEl may not have his index changed, so update event + // must be fired here as Sortable will not. + + + if (oldIndex === index(dragEl$1)) { + var update = false; + + for (var _i6 in multiDragElements) { + if (multiDragElements[_i6].sortableIndex !== index(multiDragElements[_i6])) { + update = true; + break; + } + } + + if (update) { + dispatchSortableEvent('update'); + } + } + } // Must be done after capturing individual rects (scroll bar) + + + for (var _i7 in multiDragElements) { + unsetRect(multiDragElements[_i7]); + } + + toSortable.animateAll(); + } + + multiDragSortable = toSortable; + } // Remove clones if necessary + + + if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { + for (var _i8 in multiDragClones) { + multiDragClones[_i8].parentNode && multiDragClones[_i8].parentNode.removeChild(multiDragClones[_i8]); + } + } + }, + nullingGlobal: function nullingGlobal() { + this.isMultiDrag = dragStarted = false; + multiDragClones.length = 0; + }, + destroy: function destroy() { + this._deselectMultiDrag(); + + off(document, 'pointerup', this._deselectMultiDrag); + off(document, 'mouseup', this._deselectMultiDrag); + off(document, 'touchend', this._deselectMultiDrag); + off(document, 'keydown', this._checkKeyDown); + off(document, 'keyup', this._checkKeyUp); + }, + _deselectMultiDrag: function _deselectMultiDrag(evt) { + if (dragStarted) return; // Only deselect if selection is in this sortable + + if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + + if (evt && closest(evt.target, this.sortable.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + + if (evt && evt.button !== 0) return; + + while (multiDragElements.length) { + var el = multiDragElements[0]; + toggleClass(el, this.sortable.options.selectedClass, false); + multiDragElements.shift(); + dispatchEvent({ + sortable: this.sortable, + rootEl: this.sortable.el, + name: 'deselect', + targetEl: el, + originalEvt: evt + }); + } + }, + _checkKeyDown: function _checkKeyDown(evt) { + if (evt.key === this.sortable.options.multiDragKey) { + this.multiDragKeyDown = true; + } + }, + _checkKeyUp: function _checkKeyUp(evt) { + if (evt.key === this.sortable.options.multiDragKey) { + this.multiDragKeyDown = false; + } + } + }; + return _extends(MultiDrag, { + // Static methods & properties + pluginName: 'multiDrag', + utils: { + /** + * Selects the provided multi-drag item + * @param {HTMLElement} el The element to be selected + */ + select: function select(el) { + var sortable = el.parentNode[expando]; + if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; + + if (multiDragSortable && multiDragSortable !== sortable) { + multiDragSortable.multiDrag._deselectMultiDrag(); + + multiDragSortable = sortable; + } + + toggleClass(el, sortable.options.selectedClass, true); + multiDragElements.push(el); + }, + + /** + * Deselects the provided multi-drag item + * @param {HTMLElement} el The element to be deselected + */ + deselect: function deselect(el) { + var sortable = el.parentNode[expando], + index = multiDragElements.indexOf(el); + if (!sortable || !sortable.options.multiDrag || !~index) return; + toggleClass(el, sortable.options.selectedClass, false); + multiDragElements.splice(index, 1); + } + }, + eventOptions: function eventOptions() { + var _this = this; + + var oldIndicies = [], + newIndicies = []; + multiDragElements.forEach(function (element) { + oldIndicies.push({ + element: element, + index: element.sortableIndex + }); // multiDragElements will already be sorted if folding + + var newIndex; + + if (folding && element !== dragEl$1) { + newIndex = -1; + } else if (folding) { + newIndex = index(element, ':not(.' + _this.options.selectedClass + ')'); + } else { + newIndex = index(element); + } + + newIndicies.push({ + element: element, + index: newIndex + }); + }); + return { + items: _toConsumableArray(multiDragElements), + clones: [].concat(multiDragClones), + oldIndicies: oldIndicies, + newIndicies: newIndicies + }; + }, + optionListeners: { + multiDragKey: function multiDragKey(key) { + key = key.toLowerCase(); + + if (key === 'ctrl') { + key = 'Control'; + } else if (key.length > 1) { + key = key.charAt(0).toUpperCase() + key.substr(1); + } + + return key; + } + } + }); + } + + function insertMultiDragElements(clonesInserted, rootEl) { + for (var i in multiDragElements) { + var target = rootEl.children[multiDragElements[i].sortableIndex + (clonesInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragElements[i], target); + } else { + rootEl.appendChild(multiDragElements[i]); + } + } + } + /** + * Insert multi-drag clones + * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted + * @param {HTMLElement} rootEl + */ + + + function insertMultiDragClones(elementsInserted, rootEl) { + for (var i in multiDragClones) { + var target = rootEl.children[multiDragClones[i].sortableIndex + (elementsInserted ? Number(i) : 0)]; + + if (target) { + rootEl.insertBefore(multiDragClones[i], target); + } else { + rootEl.appendChild(multiDragClones[i]); + } + } + } + + function removeMultiDragElements() { + for (var i in multiDragElements) { + if (multiDragElements[i] === dragEl$1) continue; + multiDragElements[i].parentNode && multiDragElements[i].parentNode.removeChild(multiDragElements[i]); + } + } + + Sortable$1.mount(new AutoScrollPlugin()); + Sortable$1.mount(Remove, Revert); + + Sortable$1.mount(new SwapPlugin()); + Sortable$1.mount(new MultiDragPlugin()); + + return Sortable$1; + +})); diff --git a/Sortable.min.js b/Sortable.min.js index 3dcf767c3..341947cd1 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,3 +1,2 @@ -/*! Sortable 1.9.0 - MIT | git://github.com/SortableJS/Sortable.git */ - -!function(t){"use strict";"function"==typeof define&&define.amd?define(t):"undefined"!=typeof module&&void 0!==module.exports?module.exports=t():window.Sortable=t()}(function(){"use strict";if("undefined"==typeof window||!window.document)return function(){throw new Error("Sortable.js requires a window with a document")};function A(t,e){if(!t||!t.getBoundingClientRect)return ut();var o=t,n=!1;do{if(o.clientWidth=n.left-i&&t<=n.right+i,a=e>=n.top-i&&e<=n.bottom+i;if(i&&r&&a)return d[o]}}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var o={};for(var n in t)o[n]=t[n];o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[Q]._onDragOver(o)}}}var mt;function bt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be HTMLElement, not "+{}.toString.call(t);this.el=t,this.options=e=Ot({},e),t[Q]=this;var o={group:null,sort:!0,disabled:!1,store:null,handle:null,scroll:!0,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0,draggable:/[uo]l/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return ht(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:D(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==bt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var n in o)!(n in e)&&(e[n]=o[n]);for(var i in vt(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?_t(t,"pointerdown",this._onTapStart):(_t(t,"mousedown",this._onTapStart),_t(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(_t(t,"dragover",this),_t(t,"dragenter",this)),d.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[])}function wt(t,e,o,n){if(t){o=o||J;do{if(null!=e&&(">"===e[0]?t.parentNode===o&&It(t,e):It(t,e))||n&&t===o)return t;if(t===o)break}while(t=(i=t).host&&i!==J&&i.host.nodeType?i.host:i.parentNode)}var i;return null}function _t(t,e,o){t.addEventListener(e,o,!T&&h)}function yt(t,e,o){t.removeEventListener(e,o,!T&&h)}function Dt(t,e,o){if(t&&e)if(t.classList)t.classList[o?"add":"remove"](e);else{var n=(" "+t.className+" ").replace(a," ").replace(" "+e+" "," ");t.className=(n+(o?" "+e:"")).replace(a," ")}}function Tt(t,e,o){var n=t&&t.style;if(n){if(void 0===o)return J.defaultView&&J.defaultView.getComputedStyle?o=J.defaultView.getComputedStyle(t,""):t.currentStyle&&(o=t.currentStyle),void 0===e?o:o[e];e in n||-1!==e.indexOf("webkit")||(e="-webkit-"+e),n[e]=o+("string"==typeof o?"":"px")}}function St(t){var e="";do{var o=Tt(t,"transform");o&&"none"!==o&&(e=o+" "+e)}while(t=t.parentNode);return window.DOMMatrix?new DOMMatrix(e):window.WebKitCSSMatrix?new WebKitCSSMatrix(e):window.CSSMatrix?new CSSMatrix(e):void 0}function Ct(t,e,o){if(t){var n=t.getElementsByTagName(e),i=0,r=n.length;if(o)for(;i"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function t(o,n){return function(){if(!mt){var t=arguments,e=this;mt=$(function(){1===t.length?o.call(e,t[0]):o.apply(e,t),mt=void 0},n)}}}function Ot(t,e){if(t&&e)for(var o in e)e.hasOwnProperty(o)&&(t[o]=e[o]);return t}function Ht(t){return o&&o.dom?o.dom(t).cloneNode(!0):e?e(t).clone(!0)[0]:t.cloneNode(!0)}function Bt(t){return $(t,0)}function Rt(t){return clearTimeout(t)}function Lt(t,e,o,n){if(t.getBoundingClientRect||t===y){var i,r,a,l,s,c,d;if(d=t!==y&&t!==ut()?(r=(i=t.getBoundingClientRect()).top,a=i.left,l=i.bottom,s=i.right,c=i.height,i.width):(a=r=0,l=window.innerHeight,s=window.innerWidth,c=window.innerHeight,window.innerWidth),n&&t!==y&&(o=o||t.parentNode,!T))do{if(o&&o.getBoundingClientRect&&"none"!==Tt(o,"transform")){var h=o.getBoundingClientRect();r-=h.top+D(Tt(o,"border-top-width")),a-=h.left+D(Tt(o,"border-left-width")),l=r+i.height,s=a+i.width;break}}while(o=o.parentNode);if(e&&t!==y){var u=St(o||t),f=u&&u.a,p=u&&u.d;u&&(l=(r/=p)+(c/=p),s=(a/=f)+(d/=f))}return{top:r,left:a,bottom:l,right:s,width:d,height:c}}}function Wt(t,e){for(var o=A(t,!0),n=Lt(t)[e];o;){var i=Lt(o)[e];if(!("top"===e||"left"===e?i<=n:n<=i))return o;if(o===ut())break;o=A(o,!1)}return!1}function Ft(t){var e=0,o=0,n=ut();if(t)do{var i=St(t),r=i.a,a=i.d;e+=t.scrollLeft*r,o+=t.scrollTop*a}while(t!==n&&(t=t.parentNode));return[e,o]}return bt.prototype={constructor:bt,_computeIsAligned:function(t){var e;if(p&&!it?(u(),e=J.elementFromPoint(t.clientX,t.clientY),f()):e=t.target,e=wt(e,this.options.draggable,this.el,!1),!at&&E&&E.parentNode===this.el){for(var o,n,i,r,a,l,s,c,d=this.el.children,h=0;h=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){E&&Mt(E),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;yt(t,"mouseup",this._disableDelayedDrag),yt(t,"touchend",this._disableDelayedDrag),yt(t,"touchcancel",this._disableDelayedDrag),yt(t,"mousemove",this._delayedDragTouchMoveHandler),yt(t,"touchmove",this._delayedDragTouchMoveHandler),yt(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||("touch"==t.pointerType?t:null),!this.nativeDraggable||e?this.options.supportPointer?_t(J,"pointermove",this._onTouchMove):_t(J,e?"touchmove":"mousemove",this._onTouchMove):(_t(E,"dragend",this),_t(M,"dragstart",this._onDragStart));try{J.selection?Bt(function(){J.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(w=!1,M&&E){this.nativeDraggable&&(_t(J,"dragover",this._handleAutoScroll),_t(J,"dragover",n));var o=this.options;!t&&Dt(E,o.dragClass,!1),Dt(E,o.ghostClass,!0),Tt(E,"transform",""),bt.active=this,t&&this._appendGhost(),Et(this,M,"start",E,M,M,P,void 0,O,void 0,e)}else this._nulling()},_emulateDragOver:function(t){if(R){if(this._lastX===R.clientX&&this._lastY===R.clientY&&!t)return;this._lastX=R.clientX,this._lastY=R.clientY,u();for(var e=J.elementFromPoint(R.clientX,R.clientY),o=e;e&&e.shadowRoot&&(e=e.shadowRoot.elementFromPoint(R.clientX,R.clientY))!==o;)o=e;if(o)do{if(o[Q])if(o[Q]._onDragOver({clientX:R.clientX,clientY:R.clientY,target:e,rootEl:o})&&!this.options.dragoverBubble)break;e=o}while(o=o.parentNode);E.parentNode[Q]._computeIsAligned(R),f()}},_onTouchMove:function(t,e){if(m){var o=this.options,n=o.fallbackTolerance,i=o.fallbackOffset,r=t.touches?t.touches[0]:t,a=p&&St(p),l=p&&a&&a.a,s=p&&a&&a.d,c=et&&b&&Ft(b),d=(r.clientX-m.clientX+i.x)/(l||1)+(c?c[0]-_[0]:0)/(l||1),h=(r.clientY-m.clientY+i.y)/(s||1)+(c?c[1]-_[1]:0)/(s||1),u=t.touches?"translate3d("+d+"px,"+h+"px,0)":"translate("+d+"px,"+h+"px)";if(!bt.active&&!w){if(n&&st(lt(r.clientX-this._lastX),lt(r.clientY-this._lastY))"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function k(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&d(t,e):d(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var h,f=/\s+/g;function P(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(f," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(f," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function b(t,e){var n="";do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function p(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=o.left-i&&t<=o.right+i,a=e>=o.top-i&&e<=o.bottom+i;if(i&&r&&a)return ft[n]}}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)n[o]=t[o];n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[L]._onDragOver(n)}}}function Ot(t){W&&W.parentNode[L]._isOutsideThisEl(t.target)}function Mt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=s({},e),t[L]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return St(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:Number.parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Mt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in _t(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&Dt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),ft.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),s(this,C())}function At(t,e,n,o,i,r,a,l){var s,c,u=t[L],d=u.options.onMove;return!window.CustomEvent||w||D?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Nt(t){t.draggable=!1}function It(){mt=!1}function kt(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Pt(t){return setTimeout(t,0)}function Rt(t){return clearTimeout(t)}Mt.prototype={constructor:Mt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(lt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,W):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0],l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){bt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&bt.push(o)}}(o),!W&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=k(l,t.draggable,o,!1))&&l.animated||V===l)){if($=F(l),tt=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return K({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),j("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=k(s,t.trim(),o,!1))return K({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),j("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!k(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!W&&n.parentNode===r)if(U=r,z=(W=n).parentNode,q=W.nextSibling,V=n,nt=a.group,it={target:Mt.dragged=W,clientX:(e||t).clientX,clientY:(e||t).clientY},this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,W.style["will-change"]="all",o=function(){j("delayEnded",i,{evt:t}),Mt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(W.draggable=!0),i._triggerDragStart(t,e),K({sortable:i,name:"choose",originalEvent:t}),P(W,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){p(W,t.trim(),Nt)}),u(l,"dragover",xt),u(l,"mousemove",xt),u(l,"touchmove",xt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,W.draggable=!0),j("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(D||w))o();else{if(Mt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){W&&Nt(W),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;r(t,"mouseup",this._disableDelayedDrag),r(t,"touchend",this._disableDelayedDrag),r(t,"touchcancel",this._disableDelayedDrag),r(t,"mousemove",this._delayedDragTouchMoveHandler),r(t,"touchmove",this._delayedDragTouchMoveHandler),r(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||("touch"==t.pointerType?t:null),!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(W,"dragend",this),u(U,"dragstart",this._onDragStart));try{document.selection?Pt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(dt=!1,U&&W){j("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",Ot);var n=this.options;t||P(W,n.dragClass,!1),P(W,n.ghostClass,!0),Mt.active=this,t&&this._appendGhost(),K({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(rt){this._lastX=rt.clientX,this._lastY=rt.clientY,Ct();for(var t=document.elementFromPoint(rt.clientX,rt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(rt.clientX,rt.clientY))!==e;)e=t;if(W.parentNode[L]._isOutsideThisEl(t),e)do{if(e[L]){if(e[L]._onDragOver({clientX:rt.clientX,clientY:rt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);Tt()}},_onTouchMove:function(t){if(it){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=G&&b(G),a=G&&r&&r.a,l=G&&r&&r.d,s=yt&&ut&&v(ut),c=(i.clientX-it.clientX+o.x)/(a||1)+(s?s[0]-vt[0]:0)/(a||1),u=(i.clientY-it.clientY+o.y)/(l||1)+(s?s[1]-vt[1]:0)/(l||1),d=t.touches?"translate3d("+c+"px,"+u+"px,0)":"translate("+c+"px,"+u+"px)";if(!Mt.active&&!dt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===W)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==At(U,l,W,o,s,i,n,!!s))return M(),l.appendChild(W),z=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=W.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(W.animated&&W.toRect||o,s.animated&&s.toRect||i,a),D=a?"top":"left",E=Y(s,null,"top","top")||Y(W,null,"top","top"),S=E?E.scrollTop:void 0;if(lt!==s&&(m=i[D],pt=!1,gt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a){var l=X(e),s=n?t.clientY:t.clientX,c=n?l.height:l.width,u=n?l.top:l.left,d=n?l.bottom:l.right,h=!1;if(!r)if(a&&ctFeatures

    Examples
  • Grid
  • Nested sortables
  • +
    Plugins
    +
  • MultiDrag
  • +
  • Swap
  • Comparisons
    Framework Support
    @@ -342,6 +345,56 @@

    Nested Sortables Example

    } + +
    +

    Plugins

    +
    +
    + +
    +

    MultiDrag

    +

    The MultiDrag plugin allows for multiple items to be dragged at a time. You can click to "select" multiple items, and then drag them as one item.

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    +
    new Sortable(multiDragDemo, {
    +	multiDrag: true, // Enable multi-drag
    +	selectedClass: 'selected', // The class applied to the selected items
    +	animation: 150
    +});
    +
    +
    +
    + +
    +

    Swap

    +

    The Swap plugin changes the behaviour of Sortable to allow for items to be swapped with eachother rather than sorted.

    +
    +
    Item 1
    +
    Item 2
    +
    Item 3
    +
    Item 4
    +
    Item 5
    +
    Item 6
    +
    +
    +
    new Sortable(swapDemo, {
    +	swap: true, // Enable swap plugin
    +	swapClass: 'highlight', // The class applied to the hovered swap item
    +	animation: 150
    +});
    +
    +
    +
    + + +
    @@ -349,6 +402,7 @@

    Comparisons


    +

    jQuery-UI

    @@ -373,7 +427,7 @@

    React

    react-sortablejs

    Angular

    -

    angular-sortablejs

    +

    ngx-sortablejs

    jQuery

    jquery-sortablejs

    @@ -386,6 +440,9 @@

    Polymer

    polymer-sortablejs

    + +

    Ember

    +

    ember-sortablejs

    diff --git a/st/app.js b/st/app.js index 2e3238761..3c9e93d06 100644 --- a/st/app.js +++ b/st/app.js @@ -8,7 +8,9 @@ var example1 = document.getElementById('example1'), example5 = document.getElementById('example5'), example6 = document.getElementById('example6'), example7 = document.getElementById('example7'), - gridDemo = document.getElementById('gridDemo'); + gridDemo = document.getElementById('gridDemo'), + multiDragDemo = document.getElementById('multiDragDemo'), + swapDemo = document.getElementById('swapDemo'); // Example 1 - Simple list new Sortable(example1, { @@ -203,3 +205,18 @@ for (var i = 0; i < nestedSortables.length; i++) { swapThreshold: 0.65 }); } + +// MultiDrag demo +new Sortable(multiDragDemo, { + multiDrag: true, + selectedClass: 'selected', + animation: 150 +}); + + +// Swap demo +new Sortable(swapDemo, { + swap: true, + swapClass: 'highlight', + animation: 150 +}); diff --git a/st/theme.css b/st/theme.css index 9ee899929..87b24343a 100644 --- a/st/theme.css +++ b/st/theme.css @@ -242,3 +242,13 @@ input[type=range]:focus::-ms-fill-upper { padding-right: 0; margin-right: 15px; } + +.selected { + background-color: #f9c7c8; + border: solid red 1px !important; + z-index: 1 !important; +} + +.highlight { + background-color: #B7F8C7; +} From b7d2614c6d813b2a9ea0aa9acd9fef2f7d9690b8 Mon Sep 17 00:00:00 2001 From: owen-m1 Date: Fri, 21 Jun 2019 11:39:28 -0400 Subject: [PATCH 30/41] add back carbon ads --- index.html | 4 ++ st/carbon.css | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 st/carbon.css diff --git a/index.html b/index.html index b52fe5850..daf62a31f 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ + @@ -20,6 +21,9 @@
    +
    + +

    SortableJS

    JavaScript library for reorderable drag-and-drop lists

    diff --git a/st/carbon.css b/st/carbon.css new file mode 100644 index 000000000..d82803583 --- /dev/null +++ b/st/carbon.css @@ -0,0 +1,147 @@ +@media (min-width: 992px) { + #carbonads { + display: block; + overflow: hidden; + padding: 10px; + box-shadow: 0 1px 3px hsla(0, 0%, 0%, .05); + border-radius: 4px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.5; + max-width: 300px; + margin-top: 50px; + font-size: 12px; + position: absolute; + background-color: #fff; + } + + #carbonads a { + text-decoration: none; + } + + #carbonads span { + position: relative; + display: block; + overflow: hidden; + } + + .carbon-img { + float: left; + margin-right: 1em; + } + + .carbon-img img { + display: block; + } + + .carbon-text { + display: block; + float: left; + max-width: calc(100% - 130px - 1em); + text-align: left; + color: #637381; + } + + .carbon-poweredby { + position: absolute; + left: 142px; + bottom: 0; + display: block; + font-size: 8px; + color: #c5cdd0; + font-weight: 500; + text-transform: uppercase; + line-height: 1; + letter-spacing: 1px; + } +} + +@media (max-width: 992px) { + #carbonads { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, + sans-serif; + --width: 728px; + --font-size: 22px; + } + + #carbonads { + display: block; + overflow: hidden; + max-width: var(--width); + position: relative; + background-color: hsl(0, 0%, 99%); + border: solid 1px #eee; + font-size: var(--font-size); + box-sizing: border-box; + } + + .detail #carbonads { + margin-top: 12px; + } + + #carbonads a { + color: inherit; + text-decoration: none; + } + + #carbonads a:hover { + color: inherit; + } + + .carbon-wrap { + display: flex; + align-items: center; + } + + carbon-img { + display: block; + float: left; + margin: 0; + max-width: var(--width); + line-height: 1; + } + + .carbon-img img { + display: block; + height: 90px; + width: auto; + } + + .carbon-text { + display: block; + float: left; + padding: 0 1em; + line-height: 1.35; + max-width: calc(100% - 130px - 2em); + text-align: left; + } + + .carbon-poweredby { + display: block; + position: absolute; + bottom: 0; + right: 0; + padding: 6px 10px; + background: repeating-linear-gradient( + -45deg, + transparent, + transparent 5px, + hsla(0, 0%, 0%, 0.025) 5px, + hsla(0, 0%, 0%, 0.025) 10px + ) + hsla(203, 11%, 95%, 0.8); + text-align: center; + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; + font-size: 8px; + border-top-left-radius: 4px; + line-height: 1; + } + + @media only screen and (min-width: 320px) and (max-width: 759px) { + .carbon-text { + font-size: 14px; + } + } +} \ No newline at end of file From f1baa7e45d03047464732ece827691b8ee0012bc Mon Sep 17 00:00:00 2001 From: owen-m1 Date: Fri, 19 Jul 2019 08:40:10 -0400 Subject: [PATCH 31/41] 1.10.0-rc3 --- Sortable.js | 488 +++++++++++++++++++++++------------------------- Sortable.min.js | 4 +- 2 files changed, 233 insertions(+), 259 deletions(-) diff --git a/Sortable.js b/Sortable.js index 165f1bf59..0f0ebe4a9 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,5 +1,5 @@ /**! - * Sortable 1.10.0-rc1 + * Sortable 1.10.0-rc3 * @author RubaXa * @author owenm * @license MIT @@ -132,27 +132,20 @@ throw new TypeError("Invalid attempt to spread non-iterable instance"); } - var version = "1.10.0-rc1"; + var version = "1.10.0-rc3"; function userAgent(pattern) { - return !!navigator.userAgent.match(pattern); + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); } - var IE11OrLess = - /*@__PURE__*/ - userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile)/i); - var Edge = - /*@__PURE__*/ - userAgent(/Edge/i); - var FireFox = - /*@__PURE__*/ - userAgent(/firefox/i); - var Safari = - /*@__PURE__*/ - userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); - var IOS = - /*@__PURE__*/ - userAgent(/iP(ad|od|hone)/i); + var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); + var Edge = userAgent(/Edge/i); + var FireFox = userAgent(/firefox/i); + var Safari = userAgent(/safari/i) && !userAgent(/chrome/i) && !userAgent(/android/i); + var IOS = userAgent(/iP(ad|od|hone)/i); + var ChromeForAndroid = userAgent(/chrome/i) && userAgent(/android/i); var captureMode = { capture: false, @@ -425,7 +418,7 @@ children = el.children; while (i < children.length) { - if (children[i].style.display !== 'none' && children[i] !== Sortable$1.ghost && children[i] !== Sortable$1.dragged && closest(children[i], options.draggable, el, false)) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { if (currentChild === childNum) { return children[i]; } @@ -449,7 +442,7 @@ function lastChild(el, selector) { var last = el.lastElementChild; - while (last && (last === Sortable$1.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { + while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { last = last.previousElementSibling; } @@ -474,7 +467,7 @@ while (el = el.previousElementSibling) { - if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable$1.clone && (!selector || matches(el, selector))) { + if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { index++; } } @@ -516,8 +509,10 @@ function indexOfObject(arr, obj) { for (var i in arr) { + if (!arr.hasOwnProperty(i)) continue; + for (var key in obj) { - if (obj[key] === arr[i][key]) return Number(i); + if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); } } @@ -634,17 +629,16 @@ animationStates = []; if (!this.options.animation) return; var children = [].slice.call(this.el.children); - - for (var i in children) { - if (css(children[i], 'display') === 'none' || children[i] === Sortable$1.ghost) continue; + children.forEach(function (child) { + if (css(child, 'display') === 'none' || child === Sortable.ghost) return; animationStates.push({ - target: children[i], - rect: getRect(children[i]) + target: child, + rect: getRect(child) }); - var fromRect = getRect(children[i]); // If animating: compensate for current animation + var fromRect = getRect(child); // If animating: compensate for current animation - if (children[i].thisAnimationDuration) { - var childMatrix = matrix(children[i], true); + if (child.thisAnimationDuration) { + var childMatrix = matrix(child, true); if (childMatrix) { fromRect.top -= childMatrix.f; @@ -652,8 +646,8 @@ } } - children[i].fromRect = fromRect; - } + child.fromRect = fromRect; + }); }, addAnimationState: function addAnimationState(state) { animationStates.push(state); @@ -664,6 +658,8 @@ }), 1); }, animateAll: function animateAll(callback) { + var _this = this; + if (!this.options.animation) { clearTimeout(animationCallbackId); if (typeof callback === 'function') callback(); @@ -672,15 +668,14 @@ var animating = false, animationTime = 0; - - for (var i in animationStates) { + animationStates.forEach(function (state) { var time = 0, - target = animationStates[i].target, + target = state.target, fromRect = target.fromRect, toRect = getRect(target), prevFromRect = target.prevFromRect, prevToRect = target.prevToRect, - animatingRect = animationStates[i].rect, + animatingRect = state.rect, targetMatrix = matrix(target, true); if (targetMatrix) { @@ -691,14 +686,14 @@ target.toRect = toRect; // If element is scrolled out of view: Do not animate - if ((isScrolledPast(target, toRect, 'bottom', 'top') || isScrolledPast(target, toRect, 'top', 'bottom') || isScrolledPast(target, toRect, 'right', 'left') || isScrolledPast(target, toRect, 'left', 'right')) && (isScrolledPast(target, animatingRect, 'bottom', 'top') || isScrolledPast(target, animatingRect, 'top', 'bottom') || isScrolledPast(target, animatingRect, 'right', 'left') || isScrolledPast(target, animatingRect, 'left', 'right')) && (isScrolledPast(target, fromRect, 'bottom', 'top') || isScrolledPast(target, fromRect, 'top', 'bottom') || isScrolledPast(target, fromRect, 'right', 'left') || isScrolledPast(target, fromRect, 'left', 'right'))) continue; + if ((isScrolledPast(target, toRect, 'bottom', 'top') || isScrolledPast(target, toRect, 'top', 'bottom') || isScrolledPast(target, toRect, 'right', 'left') || isScrolledPast(target, toRect, 'left', 'right')) && (isScrolledPast(target, animatingRect, 'bottom', 'top') || isScrolledPast(target, animatingRect, 'top', 'bottom') || isScrolledPast(target, animatingRect, 'right', 'left') || isScrolledPast(target, animatingRect, 'left', 'right')) && (isScrolledPast(target, fromRect, 'bottom', 'top') || isScrolledPast(target, fromRect, 'top', 'bottom') || isScrolledPast(target, fromRect, 'right', 'left') || isScrolledPast(target, fromRect, 'left', 'right'))) return; if (target.thisAnimationDuration) { // Could also check if animatingRect is between fromRect and toRect if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { // If returning to same place as started from animation and on same axis - time = calculateRealTime(animatingRect, prevFromRect, prevToRect, this.options); + time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); } } // if fromRect != toRect: animate @@ -708,10 +703,10 @@ target.prevToRect = toRect; if (!time) { - time = this.options.animation; + time = _this.options.animation; } - this.animate(target, animatingRect, time); + _this.animate(target, animatingRect, time); } if (time) { @@ -719,19 +714,15 @@ animationTime = Math.max(animationTime, time); clearTimeout(target.animationResetTimer); target.animationResetTimer = setTimeout(function () { - this.animationStates[this.i].target.animationTime = 0; - this.animationStates[this.i].target.prevFromRect = null; - this.animationStates[this.i].target.fromRect = null; - this.animationStates[this.i].target.prevToRect = null; - this.animationStates[this.i].target.thisAnimationDuration = null; - }.bind({ - animationStates: animationStates, - i: Number(i) - }), time); + target.animationTime = 0; + target.prevFromRect = null; + target.fromRect = null; + target.prevToRect = null; + target.thisAnimationDuration = null; + }, time); target.thisAnimationDuration = time; } - } - + }); clearTimeout(animationCallbackId); if (!animating) { @@ -790,45 +781,49 @@ mount: function mount(plugin) { // Set default static properties for (var option in defaults) { - !(option in plugin) && (plugin[option] = defaults[option]); + if (defaults.hasOwnProperty(option) && !(option in plugin)) { + plugin[option] = defaults[option]; + } } plugins.push(plugin); }, pluginEvent: function pluginEvent(eventName, sortable, evt) { + var _this = this; + this.eventCanceled = false; var eventNameGlobal = eventName + 'Global'; + plugins.forEach(function (plugin) { + if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable - for (var i in plugins) { - if (!sortable[plugins[i].pluginName]) continue; // Fire global events if it exists in this sortable - - if (sortable[plugins[i].pluginName][eventNameGlobal]) { - this.eventCanceled = !!sortable[plugins[i].pluginName][eventNameGlobal](_objectSpread({ + if (sortable[plugin.pluginName][eventNameGlobal]) { + _this.eventCanceled = !!sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ sortable: sortable }, evt)); } // Only fire plugin event if plugin is enabled in this sortable, // and plugin has event defined - if (sortable.options[plugins[i].pluginName] && sortable[plugins[i].pluginName][eventName]) { - this.eventCanceled = this.eventCanceled || !!sortable[plugins[i].pluginName][eventName](_objectSpread({ + if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { + _this.eventCanceled = _this.eventCanceled || !!sortable[plugin.pluginName][eventName](_objectSpread({ sortable: sortable }, evt)); } - } + }); }, initializePlugins: function initializePlugins(sortable, el, defaults) { - for (var i in plugins) { - var pluginName = plugins[i].pluginName; - if (!sortable.options[pluginName] && !plugins[i].initializeByDefault) continue; - var initialized = new plugins[i](sortable, el); + plugins.forEach(function (plugin) { + var pluginName = plugin.pluginName; + if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; + var initialized = new plugin(sortable, el); initialized.sortable = sortable; sortable[pluginName] = initialized; // Add default options from plugin _extends(defaults, initialized.options); - } + }); for (var option in sortable.options) { + if (!sortable.options.hasOwnProperty(option)) continue; var modified = this.modifyOption(sortable, option, sortable.options[option]); if (typeof modified !== 'undefined') { @@ -838,27 +833,23 @@ }, getEventOptions: function getEventOptions(name, sortable) { var eventOptions = {}; + plugins.forEach(function (plugin) { + if (typeof plugin.eventOptions !== 'function') return; - for (var i in plugins) { - if (typeof plugins[i].eventOptions !== 'function') continue; - - _extends(eventOptions, plugins[i].eventOptions.call(sortable, name)); - } - + _extends(eventOptions, plugin.eventOptions.call(sortable, name)); + }); return eventOptions; }, modifyOption: function modifyOption(sortable, name, value) { var modifiedValue; - - for (var i in plugins) { + plugins.forEach(function (plugin) { // Plugin must exist on the Sortable - if (!sortable[plugins[i].pluginName]) continue; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin - if (plugins[i].optionListeners && typeof plugins[i].optionListeners[name] === 'function') { - modifiedValue = plugins[i].optionListeners[name].call(sortable[plugins[i].pluginName], value); + if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { + modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); } - } - + }); return modifiedValue; } }; @@ -924,7 +915,7 @@ originalEvent = _ref.evt, data = _objectWithoutProperties(_ref, ["evt"]); - PluginManager.pluginEvent.bind(Sortable$1)(eventName, sortable, _objectSpread({ + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ dragEl: dragEl, parentEl: parentEl, ghostEl: ghostEl, @@ -935,7 +926,7 @@ cloneHidden: cloneHidden, dragStarted: moved, putSortable: putSortable, - activeSortable: Sortable$1.active, + activeSortable: Sortable.active, originalEvent: originalEvent, oldIndex: oldIndex, oldDraggableIndex: oldDraggableIndex, @@ -1012,7 +1003,7 @@ var PositionGhostAbsolutely = IOS, CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', // This will not pass for IE9, because IE9 DnD only works on anchors - supportDraggable = 'draggable' in document.createElement('div'), + supportDraggable = !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), supportCssPointerEvents = function () { // false when <= IE11 if (IE11OrLess) { @@ -1065,17 +1056,19 @@ * @return {HTMLElement} Element of the first found nearest Sortable */ _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { - for (var i in sortables) { - if (lastChild(sortables[i])) continue; - var rect = getRect(sortables[i]), - threshold = sortables[i][expando].options.emptyInsertThreshold, + var ret; + sortables.some(function (sortable) { + if (lastChild(sortable)) return; + var rect = getRect(sortable), + threshold = sortable[expando].options.emptyInsertThreshold, insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; if (threshold && insideHorizontally && insideVertically) { - return sortables[i]; + return ret = sortable; } - } + }); + return ret; }, _prepareGroup = function _prepareGroup(options) { function toFn(value, pull) { @@ -1147,7 +1140,9 @@ var event = {}; for (var i in evt) { - event[i] = evt[i]; + if (evt.hasOwnProperty(i)) { + event[i] = evt[i]; + } } event.target = event.rootEl = nearest; @@ -1171,7 +1166,7 @@ */ - function Sortable$1(el, options) { + function Sortable(el, options) { if (!(el && el.nodeType && el.nodeType === 1)) { throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); } @@ -1214,7 +1209,7 @@ dataIdAttr: 'data-id', delay: 0, delayOnTouchOnly: false, - touchStartThreshold: Number.parseInt(window.devicePixelRatio, 10) || 1, + touchStartThreshold: (Number.parseInt ? Number : window).parseInt(window.devicePixelRatio, 10) || 1, forceFallback: false, fallbackClass: 'sortable-fallback', fallbackOnBody: false, @@ -1223,7 +1218,7 @@ x: 0, y: 0 }, - supportPointer: Sortable$1.supportPointer !== false && 'PointerEvent' in window, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, emptyInsertThreshold: 5 }; PluginManager.initializePlugins(this, el, defaults); // Set default options @@ -1269,10 +1264,10 @@ _extends(this, AnimationStateManager()); } - Sortable$1.prototype = + Sortable.prototype = /** @lends Sortable.prototype */ { - constructor: Sortable$1, + constructor: Sortable, _isOutsideThisEl: function _isOutsideThisEl(target) { if (!this.el.contains(target) && target !== this.el) { lastTarget = null; @@ -1398,7 +1393,7 @@ nextEl = dragEl.nextSibling; lastDownEl = target; activeGroup = options.group; - Sortable$1.dragged = dragEl; + Sortable.dragged = dragEl; tapEvt = { target: dragEl, clientX: (touch || evt).clientX, @@ -1413,7 +1408,7 @@ evt: evt }); - if (Sortable$1.eventCanceled) { + if (Sortable.eventCanceled) { _this._onDrop(); return; @@ -1462,7 +1457,7 @@ }); // Delay is impossible for native DnD in Edge or IE if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { - if (Sortable$1.eventCanceled) { + if (Sortable.eventCanceled) { this._onDrop(); return; @@ -1512,7 +1507,7 @@ evt, /** Touch */ touch) { - touch = touch || (evt.pointerType == 'touch' ? evt : null); + touch = touch || evt.pointerType == 'touch' && evt; if (!this.nativeDraggable || touch) { if (this.options.supportPointer) { @@ -1555,7 +1550,7 @@ !fallback && toggleClass(dragEl, options.dragClass, false); toggleClass(dragEl, options.ghostClass, true); - Sortable$1.active = this; + Sortable.active = this; fallback && this._appendGhost(); // Drag start event _dispatchEvent({ @@ -1626,7 +1621,7 @@ dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1), translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; // only set the status to dragging, when we are actually dragging - if (!Sortable$1.active && !awaitingDragStarted) { + if (!Sortable.active && !awaitingDragStarted) { if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { return; } @@ -1685,7 +1680,7 @@ css(ghostEl, 'position', PositionGhostAbsolutely ? 'absolute' : 'fixed'); css(ghostEl, 'zIndex', '100000'); css(ghostEl, 'pointerEvents', 'none'); - Sortable$1.ghost = ghostEl; + Sortable.ghost = ghostEl; container.appendChild(ghostEl); } }, @@ -1702,7 +1697,7 @@ evt: evt }); - if (Sortable$1.eventCanceled) { + if (Sortable.eventCanceled) { this._onDrop(); return; @@ -1710,7 +1705,7 @@ pluginEvent('setupClone', this); - if (!Sortable$1.eventCanceled) { + if (!Sortable.eventCanceled) { cloneEl = clone(dragEl); cloneEl.draggable = false; cloneEl.style['will-change'] = ''; @@ -1718,13 +1713,13 @@ this._hideClone(); toggleClass(cloneEl, this.options.chosenClass, false); - Sortable$1.clone = cloneEl; + Sortable.clone = cloneEl; } // #1143: IFrame support workaround _this.cloneId = _nextTick(function () { pluginEvent('clone', _this); - if (Sortable$1.eventCanceled) return; + if (Sortable.eventCanceled) return; if (!_this.options.removeCloneOnHide) { rootEl.insertBefore(cloneEl, dragEl); @@ -1778,7 +1773,7 @@ revert, options = this.options, group = options.group, - activeSortable = Sortable$1.active, + activeSortable = Sortable.active, isOwner = activeGroup === group, canSort = options.sort, fromSortable = putSortable || activeSortable, @@ -1838,9 +1833,9 @@ toggleClass(dragEl, options.ghostClass, true); } - if (putSortable !== _this && _this !== Sortable$1.active) { + if (putSortable !== _this && _this !== Sortable.active) { putSortable = _this; - } else if (_this === Sortable$1.active && putSortable) { + } else if (_this === Sortable.active && putSortable) { putSortable = null; } // Animation @@ -1898,7 +1893,7 @@ target = closest(target, options.draggable, el, true); dragOverEvent('dragOver'); - if (Sortable$1.eventCanceled) return completedFired; + if (Sortable.eventCanceled) return completedFired; if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { return completed(false); @@ -1911,7 +1906,7 @@ vertical = this._getDirection(evt, target) === 'vertical'; dragRect = getRect(dragEl); dragOverEvent('dragOverValid'); - if (Sortable$1.eventCanceled) return completedFired; + if (Sortable.eventCanceled) return completedFired; if (revert) { parentEl = rootEl; // actualization @@ -1922,7 +1917,7 @@ dragOverEvent('revert'); - if (!Sortable$1.eventCanceled) { + if (!Sortable.eventCanceled) { if (nextEl) { rootEl.insertBefore(dragEl, nextEl); } else { @@ -1974,7 +1969,7 @@ isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; } - direction = _getSwapDirection(evt, target, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); + direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); var sibling; if (direction !== 0) { @@ -2071,7 +2066,7 @@ newIndex = index(dragEl); newDraggableIndex = index(dragEl, options.draggable); - if (Sortable$1.eventCanceled) { + if (Sortable.eventCanceled) { this._nulling(); return; @@ -2197,7 +2192,7 @@ } } - if (Sortable$1.active) { + if (Sortable.active) { /* jshint eqnull:true */ if (newIndex == null || newIndex === -1) { newIndex = oldIndex; @@ -2221,7 +2216,7 @@ }, _nulling: function _nulling() { pluginEvent('nulling', this); - rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable$1.dragged = Sortable$1.ghost = Sortable$1.clone = Sortable$1.active = null; + rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = lastDownEl = cloneHidden = tapEvt = touchEvt = moved = newIndex = newDraggableIndex = oldIndex = oldDraggableIndex = lastTarget = lastDirection = putSortable = activeGroup = Sortable.dragged = Sortable.ghost = Sortable.clone = Sortable.active = null; savedInputChecked.forEach(function (el) { el.checked = true; }); @@ -2371,7 +2366,7 @@ _hideClone: function _hideClone() { if (!cloneHidden) { pluginEvent('hideClone', this); - if (Sortable$1.eventCanceled) return; + if (Sortable.eventCanceled) return; css(cloneEl, 'display', 'none'); if (this.options.removeCloneOnHide && cloneEl.parentNode) { @@ -2390,7 +2385,7 @@ if (cloneHidden) { pluginEvent('showClone', this); - if (Sortable$1.eventCanceled) return; // show clone at dragEl or original position + if (Sortable.eventCanceled) return; // show clone at dragEl or original position if (rootEl.contains(dragEl) && !this.options.group.revertClone) { rootEl.insertBefore(cloneEl, dragEl); @@ -2467,9 +2462,8 @@ return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; } - function _getSwapDirection(evt, target, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { - var targetRect = getRect(target), - mouseOnAxis = vertical ? evt.clientY : evt.clientX, + function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { + var mouseOnAxis = vertical ? evt.clientY : evt.clientX, targetLength = vertical ? targetRect.height : targetRect.width, targetS1 = vertical ? targetRect.top : targetRect.left, targetS2 = vertical ? targetRect.bottom : targetRect.right, @@ -2569,12 +2563,12 @@ on(document, 'touchmove', function (evt) { - if ((Sortable$1.active || awaitingDragStarted) && evt.cancelable) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { evt.preventDefault(); } }); // Export utils - Sortable$1.utils = { + Sortable.utils = { on: on, off: off, css: css, @@ -2598,23 +2592,20 @@ * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted */ - Sortable$1.mount = function () { + Sortable.mount = function () { for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { plugins[_key] = arguments[_key]; } if (plugins[0].constructor === Array) plugins = plugins[0]; - - for (var i in plugins) { - var plugin = plugins[i]; - + plugins.forEach(function (plugin) { if (!plugin.prototype || !plugin.prototype.constructor) { throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(el)); } - if (plugin.utils) Sortable$1.utils = _objectSpread({}, Sortable$1.utils, plugin.utils); + if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); PluginManager.mount(plugin); - } + }); }; /** * Create sortable instance @@ -2623,12 +2614,12 @@ */ - Sortable$1.create = function (el, options) { - return new Sortable$1(el, options); + Sortable.create = function (el, options) { + return new Sortable(el, options); }; // Export - Sortable$1.version = version; + Sortable.version = version; var autoScrolls = [], scrollEl, @@ -3048,9 +3039,9 @@ var data = ''; if (multiDragElements.length && multiDragSortable === sortable) { - for (var i in multiDragElements) { - data += (!i ? '' : ', ') + multiDragElements[i].textContent; - } + multiDragElements.forEach(function (multiDragElement, i) { + data += (!i ? '' : ', ') + multiDragElement.textContent; + }); } else { data = dragEl.textContent; } @@ -3074,13 +3065,13 @@ var sortable = _ref2.sortable; if (!this.isMultiDrag) return; - for (var i in multiDragElements) { - multiDragClones.push(clone(multiDragElements[i])); - multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; - multiDragClones[i].draggable = false; - multiDragClones[i].style['will-change'] = ''; - toggleClass(multiDragClones[i], sortable.options.selectedClass, false); - multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], sortable.options.chosenClass, false); + for (var _i = 0; _i < multiDragElements.length; _i++) { + multiDragClones.push(clone(multiDragElements[_i])); + multiDragClones[_i].sortableIndex = multiDragElements[_i].sortableIndex; + multiDragClones[_i].draggable = false; + multiDragClones[_i].style['will-change'] = ''; + toggleClass(multiDragClones[_i], sortable.options.selectedClass, false); + multiDragElements[_i] === dragEl$1 && toggleClass(multiDragClones[_i], sortable.options.chosenClass, false); } sortable._hideClone(); @@ -3106,11 +3097,9 @@ rootEl = _ref4.rootEl; if (!this.isMultiDrag) return; insertMultiDragClones(false, rootEl); - - for (var i in multiDragClones) { - css(multiDragClones[i], 'display', ''); - } - + multiDragClones.forEach(function (clone) { + css(clone, 'display', ''); + }); cloneNowShown(); clonesHidden = false; return true; @@ -3119,15 +3108,13 @@ var sortable = _ref5.sortable, cloneNowHidden = _ref5.cloneNowHidden; if (!this.isMultiDrag) return; + multiDragClones.forEach(function (clone) { + css(clone, 'display', 'none'); - for (var i in multiDragClones) { - css(multiDragClones[i], 'display', 'none'); - - if (sortable.options.removeCloneOnHide && multiDragClones[i].parentNode) { - multiDragClones[i].parentNode.removeChild(multiDragClones[i]); + if (sortable.options.removeCloneOnHide && clone.parentNode) { + clone.parentNode.removeChild(clone); } - } - + }); cloneNowHidden(); clonesHidden = true; return true; @@ -3139,10 +3126,9 @@ multiDragSortable.multiDrag._deselectMultiDrag(); } - for (var i in multiDragElements) { - multiDragElements[i].sortableIndex = index(multiDragElements[i]); - } // Sort multi-drag elements - + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.sortableIndex = index(multiDragElement); + }); // Sort multi-drag elements multiDragElements = multiDragElements.sort(function (a, b) { return a.sortableIndex - b.sortableIndex; @@ -3163,18 +3149,15 @@ sortable.captureAnimationState(); if (sortable.options.animation) { - for (var i in multiDragElements) { - if (multiDragElements[i] === dragEl$1) continue; - css(multiDragElements[i], 'position', 'absolute'); - } - + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + css(multiDragElement, 'position', 'absolute'); + }); var dragRect = getRect(dragEl$1, false, true, true); - - for (var _i in multiDragElements) { - if (multiDragElements[_i] === dragEl$1) continue; - setRect(multiDragElements[_i], dragRect); - } - + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRect); + }); folding = true; initialFolding = true; } @@ -3185,9 +3168,9 @@ initialFolding = false; if (sortable.options.animation) { - for (var _i2 in multiDragElements) { - unsetRect(multiDragElements[_i2]); - } + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); } // Remove all auxiliary multidrag items from el, if sorting enabled @@ -3212,16 +3195,15 @@ if (multiDragElements.length > 1) { // Setup unfold animation - for (var i in multiDragElements) { + multiDragElements.forEach(function (multiDragElement) { sortable.addAnimationState({ - target: multiDragElements[i], - rect: folding ? getRect(multiDragElements[i]) : dragRect + target: multiDragElement, + rect: folding ? getRect(multiDragElement) : dragRect }); - unsetRect(multiDragElements[i]); - multiDragElements[i].fromRect = dragRect; - fromSortable.removeAnimationState(multiDragElements[i]); - } - + unsetRect(multiDragElement); + multiDragElement.fromRect = dragRect; + fromSortable.removeAnimationState(multiDragElement); + }); folding = false; insertMultiDragElements(!sortable.options.removeCloneOnHide, rootEl); } @@ -3246,15 +3228,13 @@ if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible var dragRectAbsolute = getRect(dragEl$1, false, true, true); - - for (var i in multiDragElements) { - if (multiDragElements[i] === dragEl$1) continue; - setRect(multiDragElements[i], dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted // while folding, and so that we can capture them again because old sortable will no longer be fromSortable - parentEl.appendChild(multiDragElements[i]); - } - + parentEl.appendChild(multiDragElement); + }); folding = true; } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out @@ -3272,14 +3252,14 @@ if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { - for (var _i3 in multiDragClones) { + multiDragClones.forEach(function (clone) { activeSortable.addAnimationState({ - target: multiDragClones[_i3], + target: clone, rect: clonesFromRect }); - multiDragClones[_i3].fromRect = clonesFromRect; - multiDragClones[_i3].thisAnimationDuration = null; - } + clone.fromRect = clonesFromRect; + clone.thisAnimationDuration = null; + }); } } else { activeSortable._showClone(sortable); @@ -3291,10 +3271,9 @@ var dragRect = _ref11.dragRect, isOwner = _ref11.isOwner, activeSortable = _ref11.activeSortable; - - for (var i in multiDragElements) { - multiDragElements[i].thisAnimationDuration = null; - } + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; + }); if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { clonesFromRect = _extends({}, dragRect); @@ -3346,25 +3325,25 @@ if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { // Must include lastMultiDragSelect (select it), in case modified selection from no selection // (but previous selection existed) - var n, i; + var n, _i2; if (currentIndex > lastIndex) { - i = lastIndex; + _i2 = lastIndex; n = currentIndex; } else { - i = currentIndex; + _i2 = currentIndex; n = lastIndex + 1; } - for (; i < n; i++) { - if (~multiDragElements.indexOf(children[i])) continue; - toggleClass(children[i], options.selectedClass, true); - multiDragElements.push(children[i]); + for (; _i2 < n; _i2++) { + if (~multiDragElements.indexOf(children[_i2])) continue; + toggleClass(children[_i2], options.selectedClass, true); + multiDragElements.push(children[_i2]); dispatchEvent({ sortable: sortable, rootEl: rootEl, name: 'select', - targetEl: children[i], + targetEl: children[_i2], originalEvt: evt }); } @@ -3392,55 +3371,51 @@ // Do not "unfold" after around dragEl if reverted if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { var dragRect = getRect(dragEl$1), - multiDragIndex = index(dragEl$1, ':not(.' + Sortable.active.options.selectedClass + ')'); + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; toSortable.captureAnimationState(); if (!initialFolding) { if (options.animation) { dragEl$1.fromRect = dragRect; + multiDragElements.forEach(function (multiDragElement) { + multiDragElement.thisAnimationDuration = null; - for (var _i4 in multiDragElements) { - multiDragElements[_i4].thisAnimationDuration = null; - - if (multiDragElements[_i4] !== dragEl$1) { - var rect = folding ? getRect(multiDragElements[_i4]) : dragRect; - multiDragElements[_i4].fromRect = rect; // Prepare unfold animation + if (multiDragElement !== dragEl$1) { + var rect = folding ? getRect(multiDragElement) : dragRect; + multiDragElement.fromRect = rect; // Prepare unfold animation toSortable.addAnimationState({ - target: multiDragElements[_i4], + target: multiDragElement, rect: rect }); } - } + }); } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert // properly they must all be removed removeMultiDragElements(); - - for (var _i5 in multiDragElements) { + multiDragElements.forEach(function (multiDragElement) { if (children[multiDragIndex]) { - parentEl.insertBefore(multiDragElements[_i5], children[multiDragIndex]); + parentEl.insertBefore(multiDragElement, children[multiDragIndex]); } else { - parentEl.appendChild(multiDragElements[_i5]); + parentEl.appendChild(multiDragElement); } multiDragIndex++; - } // If initial folding is done, the elements may have changed position because they are now + }); // If initial folding is done, the elements may have changed position because they are now // unfolding around dragEl, even though dragEl may not have his index changed, so update event // must be fired here as Sortable will not. - if (oldIndex === index(dragEl$1)) { var update = false; - - for (var _i6 in multiDragElements) { - if (multiDragElements[_i6].sortableIndex !== index(multiDragElements[_i6])) { + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement.sortableIndex !== index(multiDragElement)) { update = true; - break; + return; } - } + }); if (update) { dispatchSortableEvent('update'); @@ -3449,10 +3424,9 @@ } // Must be done after capturing individual rects (scroll bar) - for (var _i7 in multiDragElements) { - unsetRect(multiDragElements[_i7]); - } - + multiDragElements.forEach(function (multiDragElement) { + unsetRect(multiDragElement); + }); toSortable.animateAll(); } @@ -3461,9 +3435,9 @@ if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { - for (var _i8 in multiDragClones) { - multiDragClones[_i8].parentNode && multiDragClones[_i8].parentNode.removeChild(multiDragClones[_i8]); - } + multiDragClones.forEach(function (clone) { + clone.parentNode && clone.parentNode.removeChild(clone); + }); } }, nullingGlobal: function nullingGlobal() { @@ -3551,24 +3525,24 @@ var oldIndicies = [], newIndicies = []; - multiDragElements.forEach(function (element) { + multiDragElements.forEach(function (multiDragElement) { oldIndicies.push({ - element: element, - index: element.sortableIndex + multiDragElement: multiDragElement, + index: multiDragElement.sortableIndex }); // multiDragElements will already be sorted if folding var newIndex; - if (folding && element !== dragEl$1) { + if (folding && multiDragElement !== dragEl$1) { newIndex = -1; } else if (folding) { - newIndex = index(element, ':not(.' + _this.options.selectedClass + ')'); + newIndex = index(multiDragElement, ':not(.' + _this.options.selectedClass + ')'); } else { - newIndex = index(element); + newIndex = index(multiDragElement); } newIndicies.push({ - element: element, + multiDragElement: multiDragElement, index: newIndex }); }); @@ -3596,15 +3570,15 @@ } function insertMultiDragElements(clonesInserted, rootEl) { - for (var i in multiDragElements) { - var target = rootEl.children[multiDragElements[i].sortableIndex + (clonesInserted ? Number(i) : 0)]; + multiDragElements.forEach(function (multiDragElement) { + var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; if (target) { - rootEl.insertBefore(multiDragElements[i], target); + rootEl.insertBefore(multiDragElement, target); } else { - rootEl.appendChild(multiDragElements[i]); + rootEl.appendChild(multiDragElement); } - } + }); } /** * Insert multi-drag clones @@ -3614,30 +3588,30 @@ function insertMultiDragClones(elementsInserted, rootEl) { - for (var i in multiDragClones) { - var target = rootEl.children[multiDragClones[i].sortableIndex + (elementsInserted ? Number(i) : 0)]; + multiDragClones.forEach(function (clone) { + var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; if (target) { - rootEl.insertBefore(multiDragClones[i], target); + rootEl.insertBefore(clone, target); } else { - rootEl.appendChild(multiDragClones[i]); + rootEl.appendChild(clone); } - } + }); } function removeMultiDragElements() { - for (var i in multiDragElements) { - if (multiDragElements[i] === dragEl$1) continue; - multiDragElements[i].parentNode && multiDragElements[i].parentNode.removeChild(multiDragElements[i]); - } + multiDragElements.forEach(function (multiDragElement) { + if (multiDragElement === dragEl$1) return; + multiDragElement.parentNode && multiDragElement.parentNode.removeChild(multiDragElement); + }); } - Sortable$1.mount(new AutoScrollPlugin()); - Sortable$1.mount(Remove, Revert); + Sortable.mount(new AutoScrollPlugin()); + Sortable.mount(Remove, Revert); - Sortable$1.mount(new SwapPlugin()); - Sortable$1.mount(new MultiDragPlugin()); + Sortable.mount(new SwapPlugin()); + Sortable.mount(new MultiDragPlugin()); - return Sortable$1; + return Sortable; -})); +})); \ No newline at end of file diff --git a/Sortable.min.js b/Sortable.min.js index 341947cd1..bd16c4054 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.10.0-rc1 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function s(){return(s=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function k(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&d(t,e):d(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var h,f=/\s+/g;function P(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(f," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(f," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function b(t,e){var n="";do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function p(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=o.left-i&&t<=o.right+i,a=e>=o.top-i&&e<=o.bottom+i;if(i&&r&&a)return ft[n]}}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)n[o]=t[o];n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[L]._onDragOver(n)}}}function Ot(t){W&&W.parentNode[L]._isOutsideThisEl(t.target)}function Mt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=s({},e),t[L]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return St(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:Number.parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Mt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in _t(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&Dt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),ft.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),s(this,C())}function At(t,e,n,o,i,r,a,l){var s,c,u=t[L],d=u.options.onMove;return!window.CustomEvent||w||D?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Nt(t){t.draggable=!1}function It(){mt=!1}function kt(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Pt(t){return setTimeout(t,0)}function Rt(t){return clearTimeout(t)}Mt.prototype={constructor:Mt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(lt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,W):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0],l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){bt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&bt.push(o)}}(o),!W&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=k(l,t.draggable,o,!1))&&l.animated||V===l)){if($=F(l),tt=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return K({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),j("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=k(s,t.trim(),o,!1))return K({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),j("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!k(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!W&&n.parentNode===r)if(U=r,z=(W=n).parentNode,q=W.nextSibling,V=n,nt=a.group,it={target:Mt.dragged=W,clientX:(e||t).clientX,clientY:(e||t).clientY},this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,W.style["will-change"]="all",o=function(){j("delayEnded",i,{evt:t}),Mt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(W.draggable=!0),i._triggerDragStart(t,e),K({sortable:i,name:"choose",originalEvent:t}),P(W,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){p(W,t.trim(),Nt)}),u(l,"dragover",xt),u(l,"mousemove",xt),u(l,"touchmove",xt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,W.draggable=!0),j("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(D||w))o();else{if(Mt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){W&&Nt(W),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;r(t,"mouseup",this._disableDelayedDrag),r(t,"touchend",this._disableDelayedDrag),r(t,"touchcancel",this._disableDelayedDrag),r(t,"mousemove",this._delayedDragTouchMoveHandler),r(t,"touchmove",this._delayedDragTouchMoveHandler),r(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||("touch"==t.pointerType?t:null),!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(W,"dragend",this),u(U,"dragstart",this._onDragStart));try{document.selection?Pt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(dt=!1,U&&W){j("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",Ot);var n=this.options;t||P(W,n.dragClass,!1),P(W,n.ghostClass,!0),Mt.active=this,t&&this._appendGhost(),K({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(rt){this._lastX=rt.clientX,this._lastY=rt.clientY,Ct();for(var t=document.elementFromPoint(rt.clientX,rt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(rt.clientX,rt.clientY))!==e;)e=t;if(W.parentNode[L]._isOutsideThisEl(t),e)do{if(e[L]){if(e[L]._onDragOver({clientX:rt.clientX,clientY:rt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);Tt()}},_onTouchMove:function(t){if(it){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=G&&b(G),a=G&&r&&r.a,l=G&&r&&r.d,s=yt&&ut&&v(ut),c=(i.clientX-it.clientX+o.x)/(a||1)+(s?s[0]-vt[0]:0)/(a||1),u=(i.clientY-it.clientY+o.y)/(l||1)+(s?s[1]-vt[1]:0)/(l||1),d=t.touches?"translate3d("+c+"px,"+u+"px,0)":"translate("+c+"px,"+u+"px)";if(!Mt.active&&!dt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===W)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==At(U,l,W,o,s,i,n,!!s))return M(),l.appendChild(W),z=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=W.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(W.animated&&W.toRect||o,s.animated&&s.toRect||i,a),D=a?"top":"left",E=Y(s,null,"top","top")||Y(W,null,"top","top"),S=E?E.scrollTop:void 0;if(lt!==s&&(m=i[D],pt=!1,gt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a){var l=X(e),s=n?t.clientY:t.clientX,c=n?l.height:l.width,u=n?l.top:l.left,d=n?l.bottom:l.right,h=!1;if(!r)if(a&&ct"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function k(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&f(t,e):f(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var p,g=/\s+/g;function P(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(g," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(g," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function m(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[L]._onDragOver(n)}}}function At(t){G&&G.parentNode[L]._isOutsideThisEl(t.target)}function Nt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[L]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ct(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Nt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in j.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in Tt(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&_t,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?d(t,"pointerdown",this._onTapStart):(d(t,"mousedown",this._onTapStart),d(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(d(t,"dragover",this),d(t,"dragenter",this)),gt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function It(t,e,n,o,i,r,a,l){var s,c,u=t[L],d=u.options.onMove;return!window.CustomEvent||y||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function kt(t){t.draggable=!1}function Pt(){wt=!1}function Rt(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Xt(t){return setTimeout(t,0)}function Yt(t){return clearTimeout(t)}Nt.prototype={constructor:Nt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ct=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,G):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0],l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){yt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&yt.push(o)}}(o),!G&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=k(l,t.draggable,o,!1))&&l.animated||Q===l)){if(tt=F(l),nt=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return z({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),W("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=k(s,t.trim(),o,!1))return z({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),W("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!k(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!G&&n.parentNode===r)if(V=r,U=(G=n).parentNode,Z=G.nextSibling,Q=n,it=a.group,at={target:Nt.dragged=G,clientX:(e||t).clientX,clientY:(e||t).clientY},this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,G.style["will-change"]="all",o=function(){W("delayEnded",i,{evt:t}),Nt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(G.draggable=!0),i._triggerDragStart(t,e),z({sortable:i,name:"choose",originalEvent:t}),P(G,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){m(G,t.trim(),kt)}),d(l,"dragover",Mt),d(l,"mousemove",Mt),d(l,"touchmove",Mt),d(l,"mouseup",i._onDrop),d(l,"touchend",i._onDrop),d(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,G.draggable=!0),W("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||y))o();else{if(Nt.eventCanceled)return void this._onDrop();d(l,"mouseup",i._disableDelayedDrag),d(l,"touchend",i._disableDelayedDrag),d(l,"touchcancel",i._disableDelayedDrag),d(l,"mousemove",i._delayedDragTouchMoveHandler),d(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&d(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){G&&kt(G),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;h(t,"mouseup",this._disableDelayedDrag),h(t,"touchend",this._disableDelayedDrag),h(t,"touchcancel",this._disableDelayedDrag),h(t,"mousemove",this._delayedDragTouchMoveHandler),h(t,"touchmove",this._delayedDragTouchMoveHandler),h(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?d(document,"pointermove",this._onTouchMove):d(document,e?"touchmove":"mousemove",this._onTouchMove):(d(G,"dragend",this),d(V,"dragstart",this._onDragStart));try{document.selection?Xt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(ft=!1,V&&G){W("dragStarted",this,{evt:e}),this.nativeDraggable&&d(document,"dragover",At);var n=this.options;t||P(G,n.dragClass,!1),P(G,n.ghostClass,!0),Nt.active=this,t&&this._appendGhost(),z({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(lt){this._lastX=lt.clientX,this._lastY=lt.clientY,xt();for(var t=document.elementFromPoint(lt.clientX,lt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(lt.clientX,lt.clientY))!==e;)e=t;if(G.parentNode[L]._isOutsideThisEl(t),e)do{if(e[L]){if(e[L]._onDragOver({clientX:lt.clientX,clientY:lt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);Ot()}},_onTouchMove:function(t){if(at){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=q&&v(q),a=q&&r&&r.a,l=q&&r&&r.d,s=Et&&ht&&w(ht),c=(i.clientX-at.clientX+o.x)/(a||1)+(s?s[0]-bt[0]:0)/(a||1),u=(i.clientY-at.clientY+o.y)/(l||1)+(s?s[1]-bt[1]:0)/(l||1),d=t.touches?"translate3d("+c+"px,"+u+"px,0)":"translate("+c+"px,"+u+"px)";if(!Nt.active&&!ft){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===G)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==It(V,l,G,o,s,i,n,!!s))return M(),l.appendChild(G),U=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,w=G.parentNode!==l,y=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(G.animated&&G.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,null,"top","top")||Y(G,null,"top","top"),_=D?D.scrollTop:void 0;if(ct!==s&&(m=i[E],vt=!1,mt=!y&&e.invertSwap||w),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&dt Date: Sun, 16 Feb 2020 18:24:57 -0500 Subject: [PATCH 32/41] Add fallbackTolerance to multidrag example --- index.html | 1 + st/app.js | 1 + 2 files changed, 2 insertions(+) diff --git a/index.html b/index.html index daf62a31f..103cdfa6e 100644 --- a/index.html +++ b/index.html @@ -370,6 +370,7 @@

    MultiDrag

    new Sortable(multiDragDemo, {
     	multiDrag: true, // Enable multi-drag
     	selectedClass: 'selected', // The class applied to the selected items
    +	fallbackTolerance: 3, // So that we can select items on mobile
     	animation: 150
     });
    diff --git a/st/app.js b/st/app.js index 3c9e93d06..7316b90e7 100644 --- a/st/app.js +++ b/st/app.js @@ -210,6 +210,7 @@ for (var i = 0; i < nestedSortables.length; i++) { new Sortable(multiDragDemo, { multiDrag: true, selectedClass: 'selected', + fallbackTolerance: 3, // So that we can select items on mobile animation: 150 }); From c3440b34ae327eafa0273426330db0601205ed54 Mon Sep 17 00:00:00 2001 From: owen Date: Sun, 16 Feb 2020 18:44:47 -0500 Subject: [PATCH 33/41] 1.10.2 --- Sortable.js | 396 +++++++++++++++++++++++++++++------------------- Sortable.min.js | 4 +- 2 files changed, 246 insertions(+), 154 deletions(-) diff --git a/Sortable.js b/Sortable.js index 0f0ebe4a9..63579fc00 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,5 +1,5 @@ /**! - * Sortable 1.10.0-rc3 + * Sortable 1.10.2 * @author RubaXa * @author owenm * @license MIT @@ -132,12 +132,14 @@ throw new TypeError("Invalid attempt to spread non-iterable instance"); } - var version = "1.10.0-rc3"; + var version = "1.10.2"; function userAgent(pattern) { - return !! - /*@__PURE__*/ - navigator.userAgent.match(pattern); + if (typeof window !== 'undefined' && window.navigator) { + return !! + /*@__PURE__*/ + navigator.userAgent.match(pattern); + } } var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); @@ -250,17 +252,21 @@ function matrix(el, selfOnly) { var appliedTransforms = ''; - do { - var transform = css(el, 'transform'); + if (typeof el === 'string') { + appliedTransforms = el; + } else { + do { + var transform = css(el, 'transform'); - if (transform && transform !== 'none') { - appliedTransforms = transform + ' ' + appliedTransforms; - } - /* jshint boss:true */ + if (transform && transform !== 'none') { + appliedTransforms = transform + ' ' + appliedTransforms; + } + /* jshint boss:true */ - } while (!selfOnly && (el = el.parentNode)); + } while (!selfOnly && (el = el.parentNode)); + } - var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix; + var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix; /*jshint -W056 */ return matrixFn && new matrixFn(appliedTransforms); @@ -285,10 +291,12 @@ } function getWindowScrollingElement() { - if (IE11OrLess) { - return document.documentElement; + var scrollingElement = document.scrollingElement; + + if (scrollingElement) { + return scrollingElement; } else { - return document.scrollingElement; + return document.documentElement; } } /** @@ -373,16 +381,15 @@ /** * Checks if a side of an element is scrolled past a side of its parents * @param {HTMLElement} el The element who's side being scrolled out of view is in question - * @param {[DOMRect]} rect Optional rect of `el` to use * @param {String} elSide Side of the element in question ('top', 'left', 'right', 'bottom') * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element */ - function isScrolledPast(el, rect, elSide, parentSide) { + function isScrolledPast(el, elSide, parentSide) { var parent = getParentAutoScrollElement(el, true), - elSideVal = (rect ? rect : getRect(el))[elSide]; + elSideVal = getRect(el)[elSide]; /* jshint boss:true */ while (parent) { @@ -635,7 +642,9 @@ target: child, rect: getRect(child) }); - var fromRect = getRect(child); // If animating: compensate for current animation + + var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + if (child.thisAnimationDuration) { var childMatrix = matrix(child, true); @@ -684,9 +693,7 @@ toRect.left -= targetMatrix.e; } - target.toRect = toRect; // If element is scrolled out of view: Do not animate - - if ((isScrolledPast(target, toRect, 'bottom', 'top') || isScrolledPast(target, toRect, 'top', 'bottom') || isScrolledPast(target, toRect, 'right', 'left') || isScrolledPast(target, toRect, 'left', 'right')) && (isScrolledPast(target, animatingRect, 'bottom', 'top') || isScrolledPast(target, animatingRect, 'top', 'bottom') || isScrolledPast(target, animatingRect, 'right', 'left') || isScrolledPast(target, animatingRect, 'left', 'right')) && (isScrolledPast(target, fromRect, 'bottom', 'top') || isScrolledPast(target, fromRect, 'top', 'bottom') || isScrolledPast(target, fromRect, 'right', 'left') || isScrolledPast(target, fromRect, 'left', 'right'))) return; + target.toRect = toRect; if (target.thisAnimationDuration) { // Could also check if animatingRect is between fromRect and toRect @@ -706,7 +713,7 @@ time = _this.options.animation; } - _this.animate(target, animatingRect, time); + _this.animate(target, animatingRect, toRect, time); } if (time) { @@ -735,16 +742,15 @@ animationStates = []; }, - animate: function animate(target, prev, duration) { + animate: function animate(target, currentRect, toRect, duration) { if (duration) { css(target, 'transition', ''); css(target, 'transform', ''); - var currentRect = getRect(target), - elMatrix = matrix(this.el), + var elMatrix = matrix(this.el), scaleX = elMatrix && elMatrix.a, scaleY = elMatrix && elMatrix.d, - translateX = (prev.left - currentRect.left) / (scaleX || 1), - translateY = (prev.top - currentRect.top) / (scaleY || 1); + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); target.animatingX = !!translateX; target.animatingY = !!translateY; css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); @@ -792,12 +798,17 @@ var _this = this; this.eventCanceled = false; + + evt.cancel = function () { + _this.eventCanceled = true; + }; + var eventNameGlobal = eventName + 'Global'; plugins.forEach(function (plugin) { if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable if (sortable[plugin.pluginName][eventNameGlobal]) { - _this.eventCanceled = !!sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ sortable: sortable }, evt)); } // Only fire plugin event if plugin is enabled in this sortable, @@ -805,21 +816,22 @@ if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { - _this.eventCanceled = _this.eventCanceled || !!sortable[plugin.pluginName][eventName](_objectSpread({ + sortable[plugin.pluginName][eventName](_objectSpread({ sortable: sortable }, evt)); } }); }, - initializePlugins: function initializePlugins(sortable, el, defaults) { + initializePlugins: function initializePlugins(sortable, el, defaults, options) { plugins.forEach(function (plugin) { var pluginName = plugin.pluginName; if (!sortable.options[pluginName] && !plugin.initializeByDefault) return; - var initialized = new plugin(sortable, el); + var initialized = new plugin(sortable, el, sortable.options); initialized.sortable = sortable; + initialized.options = sortable.options; sortable[pluginName] = initialized; // Add default options from plugin - _extends(defaults, initialized.options); + _extends(defaults, initialized.defaults); }); for (var option in sortable.options) { @@ -831,14 +843,14 @@ } } }, - getEventOptions: function getEventOptions(name, sortable) { - var eventOptions = {}; + getEventProperties: function getEventProperties(name, sortable) { + var eventProperties = {}; plugins.forEach(function (plugin) { - if (typeof plugin.eventOptions !== 'function') return; + if (typeof plugin.eventProperties !== 'function') return; - _extends(eventOptions, plugin.eventOptions.call(sortable, name)); + _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); }); - return eventOptions; + return eventProperties; }, modifyOption: function modifyOption(sortable, name, value) { var modifiedValue; @@ -868,8 +880,9 @@ newDraggableIndex = _ref.newDraggableIndex, originalEvent = _ref.originalEvent, putSortable = _ref.putSortable, - eventOptions = _ref.eventOptions; - sortable = sortable || rootEl[expando]; + extraEventProperties = _ref.extraEventProperties; + sortable = sortable || rootEl && rootEl[expando]; + if (!sortable) return; var evt, options = sortable.options, onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature @@ -895,10 +908,10 @@ evt.originalEvent = originalEvent; evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; - var allEventOptions = _objectSpread({}, eventOptions, PluginManager.getEventOptions(name, sortable)); + var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); - for (var option in allEventOptions) { - evt[option] = allEventOptions[option]; + for (var option in allEventProperties) { + evt[option] = allEventProperties[option]; } if (rootEl) { @@ -963,10 +976,6 @@ }, info)); } - if (typeof window === "undefined" || !window.document) { - throw new Error("Sortable.js requires a window with a document"); - } - var dragEl, parentEl, ghostEl, @@ -986,6 +995,10 @@ sortables = [], tapEvt, touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, moved, lastTarget, lastDirection, @@ -1000,12 +1013,14 @@ savedInputChecked = []; /** @const */ - var PositionGhostAbsolutely = IOS, + var documentExists = typeof document !== 'undefined', + PositionGhostAbsolutely = IOS, CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', // This will not pass for IE9, because IE9 DnD only works on anchors - supportDraggable = !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), supportCssPointerEvents = function () { - // false when <= IE11 + if (!documentExists) return; // false when <= IE11 + if (IE11OrLess) { return false; } @@ -1032,7 +1047,7 @@ return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; } - if (child1 && firstChildCSS["float"] !== 'none') { + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; } @@ -1119,15 +1134,17 @@ }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position - document.addEventListener('click', function (evt) { - if (ignoreNextClick) { - evt.preventDefault(); - evt.stopPropagation && evt.stopPropagation(); - evt.stopImmediatePropagation && evt.stopImmediatePropagation(); - ignoreNextClick = false; - return false; - } - }, true); + if (documentExists) { + document.addEventListener('click', function (evt) { + if (ignoreNextClick) { + evt.preventDefault(); + evt.stopPropagation && evt.stopPropagation(); + evt.stopImmediatePropagation && evt.stopImmediatePropagation(); + ignoreNextClick = false; + return false; + } + }, true); + } var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { if (dragEl) { @@ -1286,7 +1303,7 @@ options = this.options, preventOnFilter = options.preventOnFilter, type = evt.type, - touch = evt.touches && evt.touches[0], + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, target = (touch || evt).target, originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, filter = options.filter; @@ -1387,6 +1404,7 @@ dragStartFn; if (target && !dragEl && target.parentNode === el) { + var dragRect = getRect(target); rootEl = el; dragEl = target; parentEl = dragEl.parentNode; @@ -1399,6 +1417,8 @@ clientX: (touch || evt).clientX, clientY: (touch || evt).clientY }; + tapDistanceLeft = tapEvt.clientX - dragRect.left; + tapDistanceTop = tapEvt.clientY - dragRect.top; this._lastX = (touch || evt).clientX; this._lastY = (touch || evt).clientY; dragEl.style['will-change'] = 'all'; @@ -1613,13 +1633,12 @@ fallbackTolerance = options.fallbackTolerance, fallbackOffset = options.fallbackOffset, touch = evt.touches ? evt.touches[0] : evt, - ghostMatrix = ghostEl && matrix(ghostEl), + ghostMatrix = ghostEl && matrix(ghostEl, true), scaleX = ghostEl && ghostMatrix && ghostMatrix.a, scaleY = ghostEl && ghostMatrix && ghostMatrix.d, relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), - dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1), - translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; // only set the status to dragging, when we are actually dragging + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging if (!Sortable.active && !awaitingDragStarted) { if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { @@ -1629,11 +1648,31 @@ this._onDragStart(evt, true); } - touchEvt = touch; - css(ghostEl, 'webkitTransform', translate3d); - css(ghostEl, 'mozTransform', translate3d); - css(ghostEl, 'msTransform', translate3d); - css(ghostEl, 'transform', translate3d); + if (ghostEl) { + if (ghostMatrix) { + ghostMatrix.e += dx - (lastDx || 0); + ghostMatrix.f += dy - (lastDy || 0); + } else { + ghostMatrix = { + a: 1, + b: 0, + c: 0, + d: 1, + e: dx, + f: dy + }; + } + + var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); + css(ghostEl, 'webkitTransform', cssMatrix); + css(ghostEl, 'mozTransform', cssMatrix); + css(ghostEl, 'msTransform', cssMatrix); + css(ghostEl, 'transform', cssMatrix); + lastDx = dx; + lastDy = dy; + touchEvt = touch; + } + evt.cancelable && evt.preventDefault(); } }, @@ -1681,7 +1720,9 @@ css(ghostEl, 'zIndex', '100000'); css(ghostEl, 'pointerEvents', 'none'); Sortable.ghost = ghostEl; - container.appendChild(ghostEl); + container.appendChild(ghostEl); // Set transform-origin + + css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); } }, _onDragStart: function _onDragStart( @@ -1960,7 +2001,7 @@ differentLevel = dragEl.parentNode !== el, differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), side1 = vertical ? 'top' : 'left', - scrolledPastTop = isScrolledPast(target, null, 'top', 'top') || isScrolledPast(dragEl, null, 'top', 'top'), + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; if (lastTarget !== target) { @@ -2061,7 +2102,8 @@ newDraggableIndex = index(dragEl, options.draggable); pluginEvent('drop', this, { evt: evt - }); // Get again after plugin event + }); + parentEl = dragEl && dragEl.parentNode; // Get again after plugin event newIndex = index(dragEl); newDraggableIndex = index(dragEl, options.draggable); @@ -2096,6 +2138,8 @@ css(document.body, 'user-select', ''); } + css(dragEl, 'transform', ''); + if (evt) { if (moved) { evt.cancelable && evt.preventDefault(); @@ -2220,7 +2264,7 @@ savedInputChecked.forEach(function (el) { el.checked = true; }); - savedInputChecked.length = 0; + savedInputChecked.length = lastDx = lastDy = 0; }, handleEvent: function handleEvent( /**Event*/ @@ -2360,6 +2404,8 @@ this._onDrop(); + this._disableDelayedDragEvents(); + sortables.splice(sortables.indexOf(this.el), 1); this.el = el = null; }, @@ -2396,7 +2442,7 @@ } if (this.options.group.revertClone) { - this._animate(dragEl, cloneEl); + this.animate(dragEl, cloneEl); } css(cloneEl, 'display', ''); @@ -2548,8 +2594,8 @@ var idx = inputs.length; while (idx--) { - var _el = inputs[idx]; - _el.checked && savedInputChecked.push(_el); + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); } } @@ -2562,11 +2608,14 @@ } // Fixed #973: - on(document, 'touchmove', function (evt) { - if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { - evt.preventDefault(); - } - }); // Export utils + if (documentExists) { + on(document, 'touchmove', function (evt) { + if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { + evt.preventDefault(); + } + }); + } // Export utils + Sortable.utils = { on: on, @@ -2587,11 +2636,21 @@ detectDirection: _detectDirection, getChild: getChild }; + /** + * Get the Sortable instance of an element + * @param {HTMLElement} element The element + * @return {Sortable|undefined} The instance of Sortable + */ + + Sortable.get = function (element) { + return element[expando]; + }; /** * Mount a plugin to Sortable * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted */ + Sortable.mount = function () { for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { plugins[_key] = arguments[_key]; @@ -2600,7 +2659,7 @@ if (plugins[0].constructor === Array) plugins = plugins[0]; plugins.forEach(function (plugin) { if (!plugin.prototype || !plugin.prototype.constructor) { - throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(el)); + throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); } if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); @@ -2632,7 +2691,7 @@ function AutoScrollPlugin() { function AutoScroll() { - this.options = { + this.defaults = { scroll: true, scrollSensitivity: 30, scrollSpeed: 10, @@ -2653,7 +2712,7 @@ if (this.sortable.nativeDraggable) { on(document, 'dragover', this._handleAutoScroll); } else { - if (this.sortable.options.supportPointer) { + if (this.options.supportPointer) { on(document, 'pointermove', this._handleFallbackAutoScroll); } else if (originalEvent.touches) { on(document, 'touchmove', this._handleFallbackAutoScroll); @@ -2666,7 +2725,7 @@ var originalEvent = _ref2.originalEvent; // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) - if (!this.sortable.options.dragOverBubble && !originalEvent.rootEl) { + if (!this.options.dragOverBubble && !originalEvent.rootEl) { this._handleAutoScroll(originalEvent); } }, @@ -2693,8 +2752,8 @@ _handleAutoScroll: function _handleAutoScroll(evt, fallback) { var _this = this; - var x = evt.clientX, - y = evt.clientY, + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, elem = document.elementFromPoint(x, y); touchEvt$1 = evt; // IE does not seem to have native autoscroll, // Edge's autoscroll seems too conditional, @@ -2724,7 +2783,7 @@ } } else { // if DnD is enabled (and browser has good autoscrolling), first autoscroll will already scroll, so get parent autoscroll of first autoscroll - if (!this.sortable.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { + if (!this.options.bubbleScroll || getParentAutoScrollElement(elem, true) === getWindowScrollingElement()) { clearAutoScrolls(); return; } @@ -2753,7 +2812,9 @@ var autoScroll = throttle(function (evt, options, rootEl, isFallback) { // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 if (!options.scroll) return; - var sens = options.scrollSensitivity, + var x = (evt.touches ? evt.touches[0] : evt).clientX, + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, speed = options.scrollSpeed, winScroller = getWindowScrollingElement(); var scrollThisInstance = false, @@ -2798,8 +2859,8 @@ canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); } - var vx = canScrollX && (Math.abs(right - evt.clientX) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - evt.clientX) <= sens && !!scrollPosX); - var vy = canScrollY && (Math.abs(bottom - evt.clientY) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - evt.clientY) <= sens && !!scrollPosY); + var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); + var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); if (!autoScrolls[layersOut]) { for (var i = 0; i <= layersOut; i++) { @@ -2856,14 +2917,19 @@ dispatchSortableEvent = _ref.dispatchSortableEvent, hideGhostForTarget = _ref.hideGhostForTarget, unhideGhostForTarget = _ref.unhideGhostForTarget; + if (!originalEvent) return; var toSortable = putSortable || activeSortable; hideGhostForTarget(); - var target = document.elementFromPoint(originalEvent.clientX, originalEvent.clientY); + var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; + var target = document.elementFromPoint(touch.clientX, touch.clientY); unhideGhostForTarget(); if (toSortable && !toSortable.el.contains(target)) { dispatchSortableEvent('spill'); - this.onSpill(dragEl); + this.onSpill({ + dragEl: dragEl, + putSortable: putSortable + }); } }; @@ -2875,9 +2941,16 @@ var oldDraggableIndex = _ref2.oldDraggableIndex; this.startIndex = oldDraggableIndex; }, - onSpill: function onSpill(dragEl) { + onSpill: function onSpill(_ref3) { + var dragEl = _ref3.dragEl, + putSortable = _ref3.putSortable; this.sortable.captureAnimationState(); - var nextSibling = getChild(this.sortable.el, this.startIndex, this.sortable.options); + + if (putSortable) { + putSortable.captureAnimationState(); + } + + var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); if (nextSibling) { this.sortable.el.insertBefore(dragEl, nextSibling); @@ -2886,6 +2959,10 @@ } this.sortable.animateAll(); + + if (putSortable) { + putSortable.animateAll(); + } }, drop: drop }; @@ -2897,10 +2974,13 @@ function Remove() {} Remove.prototype = { - onSpill: function onSpill(dragEl) { - this.sortable.captureAnimationState(); + onSpill: function onSpill(_ref4) { + var dragEl = _ref4.dragEl, + putSortable = _ref4.putSortable; + var parentSortable = putSortable || this.sortable; + parentSortable.captureAnimationState(); dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); - this.sortable.animateAll(); + parentSortable.animateAll(); }, drop: drop }; @@ -2913,7 +2993,7 @@ function SwapPlugin() { function Swap() { - this.options = { + this.defaults = { swapClass: 'sortable-swap-highlight' }; } @@ -2928,10 +3008,11 @@ target = _ref2.target, onMove = _ref2.onMove, activeSortable = _ref2.activeSortable, - changed = _ref2.changed; + changed = _ref2.changed, + cancel = _ref2.cancel; if (!activeSortable.options.swap) return; var el = this.sortable.el, - options = this.sortable.options; + options = this.options; if (target && target !== el) { var prevSwapEl = lastSwapEl; @@ -2949,14 +3030,15 @@ } changed(); - return completed(true); + completed(true); + cancel(); }, drop: function drop(_ref3) { var activeSortable = _ref3.activeSortable, putSortable = _ref3.putSortable, dragEl = _ref3.dragEl; var toSortable = putSortable || this.sortable; - var options = this.sortable.options; + var options = this.options; lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { @@ -2975,7 +3057,7 @@ }; return _extends(Swap, { pluginName: 'swap', - eventOptions: function eventOptions() { + eventProperties: function eventProperties() { return { swapItem: lastSwapEl }; @@ -3032,7 +3114,7 @@ on(document, 'keydown', this._checkKeyDown); on(document, 'keyup', this._checkKeyUp); - this.options = { + this.defaults = { selectedClass: 'sortable-selected', multiDragKey: null, setData: function setData(dataTransfer, dragEl) { @@ -3062,39 +3144,42 @@ this.isMultiDrag = ~multiDragElements.indexOf(dragEl$1); }, setupClone: function setupClone(_ref2) { - var sortable = _ref2.sortable; + var sortable = _ref2.sortable, + cancel = _ref2.cancel; if (!this.isMultiDrag) return; - for (var _i = 0; _i < multiDragElements.length; _i++) { - multiDragClones.push(clone(multiDragElements[_i])); - multiDragClones[_i].sortableIndex = multiDragElements[_i].sortableIndex; - multiDragClones[_i].draggable = false; - multiDragClones[_i].style['will-change'] = ''; - toggleClass(multiDragClones[_i], sortable.options.selectedClass, false); - multiDragElements[_i] === dragEl$1 && toggleClass(multiDragClones[_i], sortable.options.chosenClass, false); + for (var i = 0; i < multiDragElements.length; i++) { + multiDragClones.push(clone(multiDragElements[i])); + multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; + multiDragClones[i].draggable = false; + multiDragClones[i].style['will-change'] = ''; + toggleClass(multiDragClones[i], this.options.selectedClass, false); + multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); } sortable._hideClone(); - return true; + cancel(); }, clone: function clone(_ref3) { var sortable = _ref3.sortable, rootEl = _ref3.rootEl, - dispatchSortableEvent = _ref3.dispatchSortableEvent; + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; if (!this.isMultiDrag) return; - if (!sortable.options.removeCloneOnHide) { + if (!this.options.removeCloneOnHide) { if (multiDragElements.length && multiDragSortable === sortable) { insertMultiDragClones(true, rootEl); dispatchSortableEvent('clone'); - return true; + cancel(); } } }, showClone: function showClone(_ref4) { var cloneNowShown = _ref4.cloneNowShown, - rootEl = _ref4.rootEl; + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; if (!this.isMultiDrag) return; insertMultiDragClones(false, rootEl); multiDragClones.forEach(function (clone) { @@ -3102,22 +3187,25 @@ }); cloneNowShown(); clonesHidden = false; - return true; + cancel(); }, hideClone: function hideClone(_ref5) { + var _this = this; + var sortable = _ref5.sortable, - cloneNowHidden = _ref5.cloneNowHidden; + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; if (!this.isMultiDrag) return; multiDragClones.forEach(function (clone) { css(clone, 'display', 'none'); - if (sortable.options.removeCloneOnHide && clone.parentNode) { + if (_this.options.removeCloneOnHide && clone.parentNode) { clone.parentNode.removeChild(clone); } }); cloneNowHidden(); clonesHidden = true; - return true; + cancel(); }, dragStartGlobal: function dragStartGlobal(_ref6) { var sortable = _ref6.sortable; @@ -3136,10 +3224,12 @@ dragStarted = true; }, dragStarted: function dragStarted(_ref7) { + var _this2 = this; + var sortable = _ref7.sortable; if (!this.isMultiDrag) return; - if (sortable.options.sort) { + if (this.options.sort) { // Capture rects, // hide multi drag elements (by positioning them absolute), // set multi drag elements rects to dragRect, @@ -3148,7 +3238,7 @@ // unset rects & remove from DOM sortable.captureAnimationState(); - if (sortable.options.animation) { + if (this.options.animation) { multiDragElements.forEach(function (multiDragElement) { if (multiDragElement === dragEl$1) return; css(multiDragElement, 'position', 'absolute'); @@ -3167,24 +3257,26 @@ folding = false; initialFolding = false; - if (sortable.options.animation) { + if (_this2.options.animation) { multiDragElements.forEach(function (multiDragElement) { unsetRect(multiDragElement); }); } // Remove all auxiliary multidrag items from el, if sorting enabled - if (sortable.options.sort) { + if (_this2.options.sort) { removeMultiDragElements(); } }); }, dragOver: function dragOver(_ref8) { var target = _ref8.target, - completed = _ref8.completed; + completed = _ref8.completed, + cancel = _ref8.cancel; if (folding && ~multiDragElements.indexOf(target)) { - return completed(false); + completed(false); + cancel(); } }, revert: function revert(_ref9) { @@ -3205,7 +3297,7 @@ fromSortable.removeAnimationState(multiDragElement); }); folding = false; - insertMultiDragElements(!sortable.options.removeCloneOnHide, rootEl); + insertMultiDragElements(!this.options.removeCloneOnHide, rootEl); } }, dragOverCompleted: function dragOverCompleted(_ref10) { @@ -3215,7 +3307,7 @@ activeSortable = _ref10.activeSortable, parentEl = _ref10.parentEl, putSortable = _ref10.putSortable; - var options = sortable.options; + var options = this.options; if (insertion) { // Clones must be hidden before folding animation to capture dragRectAbsolute properly @@ -3298,7 +3390,7 @@ putSortable = _ref12.putSortable; var toSortable = putSortable || this.sortable; if (!evt) return; - var options = sortable.options, + var options = this.options, children = parentEl.children; // Multi-drag selection if (!dragStarted) { @@ -3318,32 +3410,32 @@ originalEvt: evt }); // Modifier activated, select from last to dragEl - if ((!options.multiDragKey || this.multiDragKeyDown) && evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { + if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { var lastIndex = index(lastMultiDragSelect), currentIndex = index(dragEl$1); if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { // Must include lastMultiDragSelect (select it), in case modified selection from no selection // (but previous selection existed) - var n, _i2; + var n, i; if (currentIndex > lastIndex) { - _i2 = lastIndex; + i = lastIndex; n = currentIndex; } else { - _i2 = currentIndex; + i = currentIndex; n = lastIndex + 1; } - for (; _i2 < n; _i2++) { - if (~multiDragElements.indexOf(children[_i2])) continue; - toggleClass(children[_i2], options.selectedClass, true); - multiDragElements.push(children[_i2]); + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); dispatchEvent({ sortable: sortable, rootEl: rootEl, name: 'select', - targetEl: children[_i2], + targetEl: children[i], originalEvt: evt }); } @@ -3444,7 +3536,7 @@ this.isMultiDrag = dragStarted = false; multiDragClones.length = 0; }, - destroy: function destroy() { + destroyGlobal: function destroyGlobal() { this._deselectMultiDrag(); off(document, 'pointerup', this._deselectMultiDrag); @@ -3454,17 +3546,17 @@ off(document, 'keyup', this._checkKeyUp); }, _deselectMultiDrag: function _deselectMultiDrag(evt) { - if (dragStarted) return; // Only deselect if selection is in this sortable + if (typeof dragStarted !== "undefined" && dragStarted) return; // Only deselect if selection is in this sortable if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable - if (evt && closest(evt.target, this.sortable.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click if (evt && evt.button !== 0) return; while (multiDragElements.length) { var el = multiDragElements[0]; - toggleClass(el, this.sortable.options.selectedClass, false); + toggleClass(el, this.options.selectedClass, false); multiDragElements.shift(); dispatchEvent({ sortable: this.sortable, @@ -3476,12 +3568,12 @@ } }, _checkKeyDown: function _checkKeyDown(evt) { - if (evt.key === this.sortable.options.multiDragKey) { + if (evt.key === this.options.multiDragKey) { this.multiDragKeyDown = true; } }, _checkKeyUp: function _checkKeyUp(evt) { - if (evt.key === this.sortable.options.multiDragKey) { + if (evt.key === this.options.multiDragKey) { this.multiDragKeyDown = false; } } @@ -3520,8 +3612,8 @@ multiDragElements.splice(index, 1); } }, - eventOptions: function eventOptions() { - var _this = this; + eventProperties: function eventProperties() { + var _this3 = this; var oldIndicies = [], newIndicies = []; @@ -3536,7 +3628,7 @@ if (folding && multiDragElement !== dragEl$1) { newIndex = -1; } else if (folding) { - newIndex = index(multiDragElement, ':not(.' + _this.options.selectedClass + ')'); + newIndex = index(multiDragElement, ':not(.' + _this3.options.selectedClass + ')'); } else { newIndex = index(multiDragElement); } @@ -3570,7 +3662,7 @@ } function insertMultiDragElements(clonesInserted, rootEl) { - multiDragElements.forEach(function (multiDragElement) { + multiDragElements.forEach(function (multiDragElement, i) { var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; if (target) { @@ -3588,7 +3680,7 @@ function insertMultiDragClones(elementsInserted, rootEl) { - multiDragClones.forEach(function (clone) { + multiDragClones.forEach(function (clone, i) { var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; if (target) { diff --git a/Sortable.min.js b/Sortable.min.js index bd16c4054..eba061497 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.10.0-rc3 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function k(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&f(t,e):f(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var p,g=/\s+/g;function P(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(g," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(g," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix;return i&&new i(n)}function m(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[L]._onDragOver(n)}}}function At(t){G&&G.parentNode[L]._isOutsideThisEl(t.target)}function Nt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[L]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ct(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Nt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in j.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in Tt(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&_t,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?d(t,"pointerdown",this._onTapStart):(d(t,"mousedown",this._onTapStart),d(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(d(t,"dragover",this),d(t,"dragenter",this)),gt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function It(t,e,n,o,i,r,a,l){var s,c,u=t[L],d=u.options.onMove;return!window.CustomEvent||y||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function kt(t){t.draggable=!1}function Pt(){wt=!1}function Rt(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Xt(t){return setTimeout(t,0)}function Yt(t){return clearTimeout(t)}Nt.prototype={constructor:Nt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ct=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,G):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0],l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){yt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&yt.push(o)}}(o),!G&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=k(l,t.draggable,o,!1))&&l.animated||Q===l)){if(tt=F(l),nt=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return z({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),W("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=k(s,t.trim(),o,!1))return z({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),W("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!k(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!G&&n.parentNode===r)if(V=r,U=(G=n).parentNode,Z=G.nextSibling,Q=n,it=a.group,at={target:Nt.dragged=G,clientX:(e||t).clientX,clientY:(e||t).clientY},this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,G.style["will-change"]="all",o=function(){W("delayEnded",i,{evt:t}),Nt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(G.draggable=!0),i._triggerDragStart(t,e),z({sortable:i,name:"choose",originalEvent:t}),P(G,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){m(G,t.trim(),kt)}),d(l,"dragover",Mt),d(l,"mousemove",Mt),d(l,"touchmove",Mt),d(l,"mouseup",i._onDrop),d(l,"touchend",i._onDrop),d(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,G.draggable=!0),W("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||y))o();else{if(Nt.eventCanceled)return void this._onDrop();d(l,"mouseup",i._disableDelayedDrag),d(l,"touchend",i._disableDelayedDrag),d(l,"touchcancel",i._disableDelayedDrag),d(l,"mousemove",i._delayedDragTouchMoveHandler),d(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&d(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){G&&kt(G),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;h(t,"mouseup",this._disableDelayedDrag),h(t,"touchend",this._disableDelayedDrag),h(t,"touchcancel",this._disableDelayedDrag),h(t,"mousemove",this._delayedDragTouchMoveHandler),h(t,"touchmove",this._delayedDragTouchMoveHandler),h(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?d(document,"pointermove",this._onTouchMove):d(document,e?"touchmove":"mousemove",this._onTouchMove):(d(G,"dragend",this),d(V,"dragstart",this._onDragStart));try{document.selection?Xt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(ft=!1,V&&G){W("dragStarted",this,{evt:e}),this.nativeDraggable&&d(document,"dragover",At);var n=this.options;t||P(G,n.dragClass,!1),P(G,n.ghostClass,!0),Nt.active=this,t&&this._appendGhost(),z({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(lt){this._lastX=lt.clientX,this._lastY=lt.clientY,xt();for(var t=document.elementFromPoint(lt.clientX,lt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(lt.clientX,lt.clientY))!==e;)e=t;if(G.parentNode[L]._isOutsideThisEl(t),e)do{if(e[L]){if(e[L]._onDragOver({clientX:lt.clientX,clientY:lt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);Ot()}},_onTouchMove:function(t){if(at){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=q&&v(q),a=q&&r&&r.a,l=q&&r&&r.d,s=Et&&ht&&w(ht),c=(i.clientX-at.clientX+o.x)/(a||1)+(s?s[0]-bt[0]:0)/(a||1),u=(i.clientY-at.clientY+o.y)/(l||1)+(s?s[1]-bt[1]:0)/(l||1),d=t.touches?"translate3d("+c+"px,"+u+"px,0)":"translate("+c+"px,"+u+"px)";if(!Nt.active&&!ft){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===G)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==It(V,l,G,o,s,i,n,!!s))return M(),l.appendChild(G),U=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,w=G.parentNode!==l,y=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(G.animated&&G.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,null,"top","top")||Y(G,null,"top","top"),_=D?D.scrollTop:void 0;if(ct!==s&&(m=i[E],vt=!1,mt=!y&&e.invertSwap||w),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&dt"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in At(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){St.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&St.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),u(l,"dragover",Pt),u(l,"mousemove",Pt),u(l,"touchmove",Pt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;d(t,"mouseup",this._disableDelayedDrag),d(t,"touchend",this._disableDelayedDrag),d(t,"touchcancel",this._disableDelayedDrag),d(t,"mousemove",this._delayedDragTouchMoveHandler),d(t,"touchmove",this._delayedDragTouchMoveHandler),d(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(z,"dragend",this),u(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,Nt();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U,!0),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),S=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&pt Date: Sat, 1 May 2021 22:50:43 -0400 Subject: [PATCH 34/41] remove ads --- index.html | 4 -- st/carbon.css | 147 -------------------------------------------------- 2 files changed, 151 deletions(-) delete mode 100644 st/carbon.css diff --git a/index.html b/index.html index 103cdfa6e..4a2daabc9 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,6 @@ - @@ -21,9 +20,6 @@
    -
    - -

    SortableJS

    JavaScript library for reorderable drag-and-drop lists

    diff --git a/st/carbon.css b/st/carbon.css deleted file mode 100644 index d82803583..000000000 --- a/st/carbon.css +++ /dev/null @@ -1,147 +0,0 @@ -@media (min-width: 992px) { - #carbonads { - display: block; - overflow: hidden; - padding: 10px; - box-shadow: 0 1px 3px hsla(0, 0%, 0%, .05); - border-radius: 4px; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif; - line-height: 1.5; - max-width: 300px; - margin-top: 50px; - font-size: 12px; - position: absolute; - background-color: #fff; - } - - #carbonads a { - text-decoration: none; - } - - #carbonads span { - position: relative; - display: block; - overflow: hidden; - } - - .carbon-img { - float: left; - margin-right: 1em; - } - - .carbon-img img { - display: block; - } - - .carbon-text { - display: block; - float: left; - max-width: calc(100% - 130px - 1em); - text-align: left; - color: #637381; - } - - .carbon-poweredby { - position: absolute; - left: 142px; - bottom: 0; - display: block; - font-size: 8px; - color: #c5cdd0; - font-weight: 500; - text-transform: uppercase; - line-height: 1; - letter-spacing: 1px; - } -} - -@media (max-width: 992px) { - #carbonads { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, - sans-serif; - --width: 728px; - --font-size: 22px; - } - - #carbonads { - display: block; - overflow: hidden; - max-width: var(--width); - position: relative; - background-color: hsl(0, 0%, 99%); - border: solid 1px #eee; - font-size: var(--font-size); - box-sizing: border-box; - } - - .detail #carbonads { - margin-top: 12px; - } - - #carbonads a { - color: inherit; - text-decoration: none; - } - - #carbonads a:hover { - color: inherit; - } - - .carbon-wrap { - display: flex; - align-items: center; - } - - carbon-img { - display: block; - float: left; - margin: 0; - max-width: var(--width); - line-height: 1; - } - - .carbon-img img { - display: block; - height: 90px; - width: auto; - } - - .carbon-text { - display: block; - float: left; - padding: 0 1em; - line-height: 1.35; - max-width: calc(100% - 130px - 2em); - text-align: left; - } - - .carbon-poweredby { - display: block; - position: absolute; - bottom: 0; - right: 0; - padding: 6px 10px; - background: repeating-linear-gradient( - -45deg, - transparent, - transparent 5px, - hsla(0, 0%, 0%, 0.025) 5px, - hsla(0, 0%, 0%, 0.025) 10px - ) - hsla(203, 11%, 95%, 0.8); - text-align: center; - text-transform: uppercase; - letter-spacing: 0.5px; - font-weight: 600; - font-size: 8px; - border-top-left-radius: 4px; - line-height: 1; - } - - @media only screen and (min-width: 320px) and (max-width: 759px) { - .carbon-text { - font-size: 14px; - } - } -} \ No newline at end of file From 873165bcb14fc223f79b4c5d6e6dfd77200b5280 Mon Sep 17 00:00:00 2001 From: Owen Mills Date: Sat, 1 May 2021 22:52:53 -0400 Subject: [PATCH 35/41] 1.13.0 --- Sortable.js | 26 +++++++++++++++++++------- Sortable.min.js | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Sortable.js b/Sortable.js index 63579fc00..50209234d 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,5 +1,5 @@ /**! - * Sortable 1.10.2 + * Sortable 1.13.0 * @author RubaXa * @author owenm * @license MIT @@ -132,7 +132,7 @@ throw new TypeError("Invalid attempt to spread non-iterable instance"); } - var version = "1.10.2"; + var version = "1.13.0"; function userAgent(pattern) { if (typeof window !== 'undefined' && window.navigator) { @@ -314,7 +314,7 @@ if (!el.getBoundingClientRect && el !== window) return; var elRect, top, left, bottom, right, height, width; - if (el !== window && el !== getWindowScrollingElement()) { + if (el !== window && el.parentNode && el !== getWindowScrollingElement()) { elRect = el.getBoundingClientRect(); top = elRect.top; left = elRect.left; @@ -754,7 +754,7 @@ target.animatingX = !!translateX; target.animatingY = !!translateY; css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); - repaint(target); // repaint + this.forRepaintDummy = repaint(target); // repaint css(target, 'transition', 'transform ' + duration + 'ms' + (this.options.easing ? ' ' + this.options.easing : '')); css(target, 'transform', 'translate3d(0,0,0)'); @@ -792,6 +792,11 @@ } } + plugins.forEach(function (p) { + if (p.pluginName === plugin.pluginName) { + throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once"); + } + }); plugins.push(plugin); }, pluginEvent: function pluginEvent(eventName, sortable, evt) { @@ -1235,7 +1240,7 @@ x: 0, y: 0 }, - supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window, + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari, emptyInsertThreshold: 5 }; PluginManager.initializePlugins(this, el, defaults); // Set default options @@ -1322,6 +1327,11 @@ if (originalTarget.isContentEditable) { return; + } // Safari ignores further event handling after mousedown + + + if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') { + return; } target = closest(target, options.draggable, el, false); @@ -2319,7 +2329,7 @@ * Sorts the elements according to the array. * @param {String[]} order order of the items */ - sort: function sort(order) { + sort: function sort(order, useAnimation) { var items = {}, rootEl = this.el; this.toArray().forEach(function (id, i) { @@ -2329,12 +2339,14 @@ items[id] = el; } }, this); + useAnimation && this.captureAnimationState(); order.forEach(function (id) { if (items[id]) { rootEl.removeChild(items[id]); rootEl.appendChild(items[id]); } }); + useAnimation && this.animateAll(); }, /** @@ -2433,7 +2445,7 @@ pluginEvent('showClone', this); if (Sortable.eventCanceled) return; // show clone at dragEl or original position - if (rootEl.contains(dragEl) && !this.options.group.revertClone) { + if (dragEl.parentNode == rootEl && !this.options.group.revertClone) { rootEl.insertBefore(cloneEl, dragEl); } else if (nextEl) { rootEl.insertBefore(cloneEl, nextEl); diff --git a/Sortable.min.js b/Sortable.min.js index eba061497..4fe7f0c36 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.10.2 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in At(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?u(t,"pointerdown",this._onTapStart):(u(t,"mousedown",this._onTapStart),u(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(u(t,"dragover",this),u(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){St.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&St.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled||s.isContentEditable||(l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),u(l,"dragover",Pt),u(l,"mousemove",Pt),u(l,"touchmove",Pt),u(l,"mouseup",i._onDrop),u(l,"touchend",i._onDrop),u(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();u(l,"mouseup",i._disableDelayedDrag),u(l,"touchend",i._disableDelayedDrag),u(l,"touchcancel",i._disableDelayedDrag),u(l,"mousemove",i._delayedDragTouchMoveHandler),u(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&u(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;d(t,"mouseup",this._disableDelayedDrag),d(t,"touchend",this._disableDelayedDrag),d(t,"touchcancel",this._disableDelayedDrag),d(t,"mousemove",this._delayedDragTouchMoveHandler),d(t,"touchmove",this._delayedDragTouchMoveHandler),d(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?u(document,"pointermove",this._onTouchMove):u(document,e?"touchmove":"mousemove",this._onTouchMove):(u(z,"dragend",this),u(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&u(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,Nt();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U,!0),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return A(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,N(),A(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),S=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&pt"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in Nt(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?d(t,"pointerdown",this._onTapStart):(d(t,"mousedown",this._onTapStart),d(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(d(t,"dragover",this),d(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){St.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&St.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),d(l,"dragover",Pt),d(l,"mousemove",Pt),d(l,"touchmove",Pt),d(l,"mouseup",i._onDrop),d(l,"touchend",i._onDrop),d(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();d(l,"mouseup",i._disableDelayedDrag),d(l,"touchend",i._disableDelayedDrag),d(l,"touchcancel",i._disableDelayedDrag),d(l,"mousemove",i._delayedDragTouchMoveHandler),d(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&d(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;s(t,"mouseup",this._disableDelayedDrag),s(t,"touchend",this._disableDelayedDrag),s(t,"touchcancel",this._disableDelayedDrag),s(t,"mousemove",this._delayedDragTouchMoveHandler),s(t,"touchmove",this._delayedDragTouchMoveHandler),s(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?d(document,"pointermove",this._onTouchMove):d(document,e?"touchmove":"mousemove",this._onTouchMove):(d(z,"dragend",this),d(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&d(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,At();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U,!0),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return N(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,A(),N(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),S=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&pt Date: Sat, 1 May 2021 23:54:03 -0400 Subject: [PATCH 36/41] Fix ads --- index.html | 4 ++ st/carbon.css | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 st/carbon.css diff --git a/index.html b/index.html index 4a2daabc9..103cdfa6e 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ + @@ -20,6 +21,9 @@
    +
    + +

    SortableJS

    JavaScript library for reorderable drag-and-drop lists

    diff --git a/st/carbon.css b/st/carbon.css new file mode 100644 index 000000000..d82803583 --- /dev/null +++ b/st/carbon.css @@ -0,0 +1,147 @@ +@media (min-width: 992px) { + #carbonads { + display: block; + overflow: hidden; + padding: 10px; + box-shadow: 0 1px 3px hsla(0, 0%, 0%, .05); + border-radius: 4px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.5; + max-width: 300px; + margin-top: 50px; + font-size: 12px; + position: absolute; + background-color: #fff; + } + + #carbonads a { + text-decoration: none; + } + + #carbonads span { + position: relative; + display: block; + overflow: hidden; + } + + .carbon-img { + float: left; + margin-right: 1em; + } + + .carbon-img img { + display: block; + } + + .carbon-text { + display: block; + float: left; + max-width: calc(100% - 130px - 1em); + text-align: left; + color: #637381; + } + + .carbon-poweredby { + position: absolute; + left: 142px; + bottom: 0; + display: block; + font-size: 8px; + color: #c5cdd0; + font-weight: 500; + text-transform: uppercase; + line-height: 1; + letter-spacing: 1px; + } +} + +@media (max-width: 992px) { + #carbonads { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, + sans-serif; + --width: 728px; + --font-size: 22px; + } + + #carbonads { + display: block; + overflow: hidden; + max-width: var(--width); + position: relative; + background-color: hsl(0, 0%, 99%); + border: solid 1px #eee; + font-size: var(--font-size); + box-sizing: border-box; + } + + .detail #carbonads { + margin-top: 12px; + } + + #carbonads a { + color: inherit; + text-decoration: none; + } + + #carbonads a:hover { + color: inherit; + } + + .carbon-wrap { + display: flex; + align-items: center; + } + + carbon-img { + display: block; + float: left; + margin: 0; + max-width: var(--width); + line-height: 1; + } + + .carbon-img img { + display: block; + height: 90px; + width: auto; + } + + .carbon-text { + display: block; + float: left; + padding: 0 1em; + line-height: 1.35; + max-width: calc(100% - 130px - 2em); + text-align: left; + } + + .carbon-poweredby { + display: block; + position: absolute; + bottom: 0; + right: 0; + padding: 6px 10px; + background: repeating-linear-gradient( + -45deg, + transparent, + transparent 5px, + hsla(0, 0%, 0%, 0.025) 5px, + hsla(0, 0%, 0%, 0.025) 10px + ) + hsla(203, 11%, 95%, 0.8); + text-align: center; + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; + font-size: 8px; + border-top-left-radius: 4px; + line-height: 1; + } + + @media only screen and (min-width: 320px) and (max-width: 759px) { + .carbon-text { + font-size: 14px; + } + } +} \ No newline at end of file From f08efa4e5a02cf1c3fc57c0503bbd908466ba8c2 Mon Sep 17 00:00:00 2001 From: Owen Mills Date: Sun, 4 Jul 2021 22:22:30 -0400 Subject: [PATCH 37/41] 1.14.0 --- Sortable.js | 172 ++++++++++++++++++++++++++++++++---------------- Sortable.min.js | 4 +- 2 files changed, 119 insertions(+), 57 deletions(-) diff --git a/Sortable.js b/Sortable.js index 50209234d..38da0c7ee 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,16 +1,56 @@ /**! - * Sortable 1.13.0 - * @author RubaXa - * @author owenm + * Sortable 1.14.0 + * @author RubaXa + * @author owenm * @license MIT */ -(function (global, factory) { + (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.Sortable = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; + + function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + + if (enumerableOnly) { + symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + } + + keys.push.apply(keys, symbols); + } + + return keys; + } + + function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; + } function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; @@ -57,25 +97,6 @@ return _extends.apply(this, arguments); } - function _objectSpread(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {}; - var ownKeys = Object.keys(source); - - if (typeof Object.getOwnPropertySymbols === 'function') { - ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { - return Object.getOwnPropertyDescriptor(source, sym).enumerable; - })); - } - - ownKeys.forEach(function (key) { - _defineProperty(target, key, source[key]); - }); - } - - return target; - } - function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; @@ -113,32 +134,43 @@ } function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } + if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); + } + + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + + return arr2; } function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - var version = "1.13.0"; + var version = "1.14.0"; function userAgent(pattern) { if (typeof window !== 'undefined' && window.navigator) { - return !! - /*@__PURE__*/ - navigator.userAgent.match(pattern); + return !! /*@__PURE__*/navigator.userAgent.match(pattern); } } @@ -419,13 +451,13 @@ */ - function getChild(el, childNum, options) { + function getChild(el, childNum, options, includeDragEl) { var currentChild = 0, i = 0, children = el.children; while (i < children.length) { - if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && children[i] !== Sortable.dragged && closest(children[i], options.draggable, el, false)) { + if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) { if (currentChild === childNum) { return children[i]; } @@ -643,7 +675,7 @@ rect: getRect(child) }); - var fromRect = _objectSpread({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation + var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation if (child.thisAnimationDuration) { @@ -813,7 +845,7 @@ if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable if (sortable[plugin.pluginName][eventNameGlobal]) { - sortable[plugin.pluginName][eventNameGlobal](_objectSpread({ + sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({ sortable: sortable }, evt)); } // Only fire plugin event if plugin is enabled in this sortable, @@ -821,7 +853,7 @@ if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { - sortable[plugin.pluginName][eventName](_objectSpread({ + sortable[plugin.pluginName][eventName](_objectSpread2({ sortable: sortable }, evt)); } @@ -913,7 +945,7 @@ evt.originalEvent = originalEvent; evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; - var allEventProperties = _objectSpread({}, extraEventProperties, PluginManager.getEventProperties(name, sortable)); + var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable)); for (var option in allEventProperties) { evt[option] = allEventProperties[option]; @@ -928,12 +960,14 @@ } } + var _excluded = ["evt"]; + var pluginEvent = function pluginEvent(eventName, sortable) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, originalEvent = _ref.evt, - data = _objectWithoutProperties(_ref, ["evt"]); + data = _objectWithoutProperties(_ref, _excluded); - PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread({ + PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({ dragEl: dragEl, parentEl: parentEl, ghostEl: ghostEl, @@ -969,7 +1003,7 @@ }; function _dispatchEvent(info) { - dispatchEvent(_objectSpread({ + dispatchEvent(_objectSpread2({ putSortable: putSortable, cloneEl: cloneEl, targetEl: dragEl, @@ -1078,13 +1112,13 @@ _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { var ret; sortables.some(function (sortable) { - if (lastChild(sortable)) return; + var threshold = sortable[expando].options.emptyInsertThreshold; + if (!threshold || lastChild(sortable)) return; var rect = getRect(sortable), - threshold = sortable[expando].options.emptyInsertThreshold, insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; - if (threshold && insideHorizontally && insideVertically) { + if (insideHorizontally && insideVertically) { return ret = sortable; } }); @@ -1835,7 +1869,7 @@ if (_silent) return; function dragOverEvent(name, extra) { - pluginEvent(name, _this, _objectSpread({ + pluginEvent(name, _this, _objectSpread2({ evt: evt, isOwner: isOwner, axis: vertical ? 'vertical' : 'horizontal', @@ -1952,7 +1986,7 @@ ignoreNextClick = false; - if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { vertical = this._getDirection(evt, target) === 'vertical'; dragRect = getRect(dragEl); @@ -1982,10 +2016,11 @@ var elLastChild = lastChild(el, options.draggable); if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { + // Insert to end of list // If already at end of list: Do not insert if (elLastChild === dragEl) { return completed(false); - } // assign target only if condition is true + } // if there is a last element, it is the target if (elLastChild && el === evt.target) { @@ -2001,6 +2036,25 @@ el.appendChild(dragEl); parentEl = el; // actualization + changed(); + return completed(true); + } + } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) { + // Insert to start of list + var firstChild = getChild(el, 0, options, true); + + if (firstChild === dragEl) { + return completed(false); + } + + target = firstChild; + targetRect = getRect(target); + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) { + capture(); + el.insertBefore(dragEl, firstChild); + parentEl = el; // actualization + changed(); return completed(true); } @@ -2514,6 +2568,12 @@ _silent = false; } + function _ghostIsFirst(evt, vertical, sortable) { + var rect = getRect(getChild(sortable.el, 0, sortable.options, true)); + var spacer = 10; + return vertical ? evt.clientX < rect.left - spacer || evt.clientY < rect.top && evt.clientX < rect.right : evt.clientY < rect.top - spacer || evt.clientY < rect.bottom && evt.clientX < rect.left; + } + function _ghostIsLast(evt, vertical, sortable) { var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); var spacer = 10; @@ -2674,7 +2734,7 @@ throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); } - if (plugin.utils) Sortable.utils = _objectSpread({}, Sortable.utils, plugin.utils); + if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils); PluginManager.mount(plugin); }); }; @@ -2705,6 +2765,7 @@ function AutoScroll() { this.defaults = { scroll: true, + forceAutoScrollFallback: false, scrollSensitivity: 30, scrollSpeed: 10, bubbleScroll: true @@ -2772,7 +2833,7 @@ // MACOS Safari does not have autoscroll, // Firefox and Chrome are good - if (fallback || Edge || IE11OrLess || Safari) { + if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) { autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change var ogElemScroller = getParentAutoScrollElement(elem, true); @@ -3472,7 +3533,8 @@ if (dragStarted && this.isMultiDrag) { - // Do not "unfold" after around dragEl if reverted + folding = false; // Do not "unfold" after around dragEl if reverted + if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { var dragRect = getRect(dragEl$1), multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); @@ -3718,4 +3780,4 @@ return Sortable; -})); \ No newline at end of file +}))); \ No newline at end of file diff --git a/Sortable.min.js b/Sortable.min.js index 4fe7f0c36..7ba6b5903 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.13.0 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||o&&t===n)return t;if(t===n)break}while(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode)}var i;return null}var f,p=/\s+/g;function k(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var o=(" "+t.className+" ").replace(p," ").replace(" "+e+" "," ");t.className=(o+(n?" "+e:"")).replace(p," ")}}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in o||-1!==e.indexOf("webkit")||(e="-webkit-"+e),o[e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform");o&&"none"!==o&&(n=o+" "+n)}while(!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function g(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=e.left-n&&r<=e.right+n,i=a>=e.top-n&&a<=e.bottom+n;return n&&o&&i?l=t:void 0}}),l}((t=t.touches?t.touches[0]:t).clientX,t.clientY);if(e){var n={};for(var o in t)t.hasOwnProperty(o)&&(n[o]=t[o]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[j]._onDragOver(n)}}}function kt(t){z&&z.parentNode[j]._isOutsideThisEl(t.target)}function Rt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Ot(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Rt.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(var o in O.initializePlugins(this,t,n),n)o in e||(e[o]=n[o]);for(var i in Nt(e),this)"_"===i.charAt(0)&&"function"==typeof this[i]&&(this[i]=this[i].bind(this));this.nativeDraggable=!e.forceFallback&&xt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?d(t,"pointerdown",this._onTapStart):(d(t,"mousedown",this._onTapStart),d(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(d(t,"dragover",this),d(t,"dragenter",this)),bt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,T())}function Xt(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||w||E?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),d&&(c=d.call(u,s,a)),c}function Yt(t){t.draggable=!1}function Bt(){Dt=!1}function Ft(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;n--;)o+=e.charCodeAt(n);return o.toString(36)}function Ht(t){return setTimeout(t,0)}function Lt(t){return clearTimeout(t)}Rt.prototype={constructor:Rt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(function(t){St.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&St.push(o)}}(o),!z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||Z===l)){if(J=F(l),et=F(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return W({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),K("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c&&(c=c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return W({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),K("filter",n,{evt:e}),!0})))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;if(n&&!z&&n.parentNode===r){var s=X(n);if(q=r,G=(z=n).parentNode,V=z.nextSibling,Z=n,ot=a.group,rt={target:Rt.dragged=z,clientX:(e||t).clientX,clientY:(e||t).clientY},ct=rt.clientX-s.left,ut=rt.clientY-s.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,z.style["will-change"]="all",o=function(){K("delayEnded",i,{evt:t}),Rt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!c&&i.nativeDraggable&&(z.draggable=!0),i._triggerDragStart(t,e),W({sortable:i,name:"choose",originalEvent:t}),k(z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){g(z,t.trim(),Yt)}),d(l,"dragover",Pt),d(l,"mousemove",Pt),d(l,"touchmove",Pt),d(l,"mouseup",i._onDrop),d(l,"touchend",i._onDrop),d(l,"touchcancel",i._onDrop),c&&this.nativeDraggable&&(this.options.touchStartThreshold=4,z.draggable=!0),K("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(E||w))o();else{if(Rt.eventCanceled)return void this._onDrop();d(l,"mouseup",i._disableDelayedDrag),d(l,"touchend",i._disableDelayedDrag),d(l,"touchcancel",i._disableDelayedDrag),d(l,"mousemove",i._delayedDragTouchMoveHandler),d(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&d(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){z&&Yt(z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;s(t,"mouseup",this._disableDelayedDrag),s(t,"touchend",this._disableDelayedDrag),s(t,"touchcancel",this._disableDelayedDrag),s(t,"mousemove",this._delayedDragTouchMoveHandler),s(t,"touchmove",this._delayedDragTouchMoveHandler),s(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?d(document,"pointermove",this._onTouchMove):d(document,e?"touchmove":"mousemove",this._onTouchMove):(d(z,"dragend",this),d(q,"dragstart",this._onDragStart));try{document.selection?Ht(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(vt=!1,q&&z){K("dragStarted",this,{evt:e}),this.nativeDraggable&&d(document,"dragover",kt);var n=this.options;t||k(z,n.dragClass,!1),k(z,n.ghostClass,!0),Rt.active=this,t&&this._appendGhost(),W({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(at){this._lastX=at.clientX,this._lastY=at.clientY,At();for(var t=document.elementFromPoint(at.clientX,at.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(at.clientX,at.clientY))!==e;)e=t;if(z.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j]){if(e[j]._onDragOver({clientX:at.clientX,clientY:at.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}t=e}while(e=e.parentNode);It()}},_onTouchMove:function(t){if(rt){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=U&&v(U,!0),a=U&&r&&r.a,l=U&&r&&r.d,s=Ct&>&&b(gt),c=(i.clientX-rt.clientX+o.x)/(a||1)+(s?s[0]-Et[0]:0)/(a||1),u=(i.clientY-rt.clientY+o.y)/(l||1)+(s?s[1]-Et[1]:0)/(l||1);if(!Rt.active&&!vt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))o.right+10||t.clientX<=o.right&&t.clientY>o.bottom&&t.clientX>=o.left:t.clientX>o.right&&t.clientY>o.top||t.clientX<=o.right&&t.clientY>o.bottom+10}(n,a,this)&&!g.animated){if(g===z)return N(!1);if(g&&l===n.target&&(s=g),s&&(i=X(s)),!1!==Xt(q,l,z,o,s,i,n,!!s))return O(),l.appendChild(z),G=l,A(),N(!0)}else if(s.parentNode===l){i=X(s);var v,m,b,y=z.parentNode!==l,w=!function(t,e,n){var o=n?t.left:t.top,i=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,l=n?e.right:e.bottom,s=n?e.width:e.height;return o===a||i===l||o+r/2===a+s/2}(z.animated&&z.toRect||o,s.animated&&s.toRect||i,a),E=a?"top":"left",D=Y(s,"top","top")||Y(z,"top","top"),S=D?D.scrollTop:void 0;if(ht!==s&&(m=i[E],yt=!1,wt=!w&&e.invertSwap||y),0!==(v=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,u=o?n.top:n.left,d=o?n.bottom:n.right,h=!1;if(!a)if(l&&ptt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function N(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function I(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function P(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=P(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[j]._onDragOver(o)}}var i,r,a}function Yt(t){q&&q.parentNode[j]._isOutsideThisEl(t.target)}function Bt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return It(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Bt.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in K.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Pt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&At,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Et.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function Ft(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||k(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function jt(t){t.draggable=!1}function Ht(){Ct=!1}function Lt(t){return setTimeout(t,0)}function Kt(t){return clearTimeout(t)}Bt.prototype={constructor:Bt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(gt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,q):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Tt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Tt.push(o)}}(o),!q&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=N(l,t.draggable,o,!1))&&l.animated||J===l)){if(nt=B(l),it=B(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return U({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),z("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=N(s,t.trim(),o,!1))return U({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),z("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!N(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!q&&n.parentNode===r&&(o=k(n),$=r,V=(q=n).parentNode,Q=q.nextSibling,J=n,at=a.group,st={target:Bt.dragged=q,clientX:(e||t).clientX,clientY:(e||t).clientY},ht=st.clientX-o.left,ft=st.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,q.style["will-change"]="all",o=function(){z("delayEnded",i,{evt:t}),Bt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(q.draggable=!0),i._triggerDragStart(t,e),U({sortable:i,name:"choose",originalEvent:t}),I(q,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(q,t.trim(),jt)}),h(l,"dragover",Xt),h(l,"mousemove",Xt),h(l,"touchmove",Xt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,q.draggable=!0),z("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Bt.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){q&&jt(q),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(q,"dragend",this),h($,"dragstart",this._onDragStart));try{document.selection?Lt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;yt=!1,$&&q?(z("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Yt),n=this.options,t||I(q,n.dragClass,!1),I(q,n.ghostClass,!0),Bt.active=this,t&&this._appendGhost(),U({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ct){this._lastX=ct.clientX,this._lastY=ct.clientY,kt();for(var t=document.elementFromPoint(ct.clientX,ct.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ct.clientX,ct.clientY))!==e;)e=t;if(q.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j])if(e[j]._onDragOver({clientX:ct.clientX,clientY:ct.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Rt()}},_onTouchMove:function(t){if(st){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=Z&&v(Z,!0),a=Z&&r&&r.a,l=Z&&r&&r.d,e=Ot&&bt&&E(bt),a=(i.clientX-st.clientX+o.x)/(a||1)+(e?e[0]-_t[0]:0)/(a||1),l=(i.clientY-st.clientY+o.y)/(l||1)+(e?e[1]-_t[1]:0)/(l||1);if(!Bt.active&&!yt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))n.right+10||t.clientX<=n.right&&t.clientY>n.bottom&&t.clientX>=n.left:t.clientX>n.right&&t.clientY>n.top||t.clientX<=n.right&&t.clientY>n.bottom+10}(n,r,this)&&!g.animated){if(g===q)return O(!1);if((l=g&&a===n.target?g:l)&&(w=k(l)),!1!==Ft($,a,q,o,l,w,n,!!l))return x(),a.appendChild(q),V=a,M(),O(!0)}else if(g&&function(t,e,n){n=k(X(n.el,0,n.options,!0));return e?t.clientX Date: Thu, 30 Nov 2023 22:22:03 +0000 Subject: [PATCH 38/41] 1.15.1 --- .gitignore | 1 + Sortable.js | 1576 +++++++++++++++++------------------------------ Sortable.min.js | 4 +- 3 files changed, 582 insertions(+), 999 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..40b878db5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/Sortable.js b/Sortable.js index 38da0c7ee..242106c14 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,10 +1,10 @@ /**! - * Sortable 1.14.0 + * Sortable 1.15.1 * @author RubaXa * @author owenm * @license MIT */ - (function (global, factory) { +(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.Sortable = factory()); @@ -12,26 +12,20 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); - if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); - if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } - keys.push.apply(keys, symbols); } - return keys; } - function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; - if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); @@ -44,10 +38,8 @@ }); } } - return target; } - function _typeof(obj) { "@babel/helpers - typeof"; @@ -60,10 +52,8 @@ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } - return _typeof(obj); } - function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { @@ -75,53 +65,40 @@ } else { obj[key] = value; } - return obj; } - function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; - for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } - return target; }; - return _extends.apply(this, arguments); } - function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; - for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } - return target; } - function _objectWithoutProperties(source, excluded) { if (source == null) return {}; - var target = _objectWithoutPropertiesLoose(source, excluded); - var key, i; - if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; @@ -129,22 +106,17 @@ target[key] = source[key]; } } - return target; } - function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } - function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } - function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } - function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); @@ -153,27 +125,22 @@ if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } - function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - return arr2; } - function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - var version = "1.14.0"; + var version = "1.15.1"; function userAgent(pattern) { if (typeof window !== 'undefined' && window.navigator) { return !! /*@__PURE__*/navigator.userAgent.match(pattern); } } - var IE11OrLess = userAgent(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i); var Edge = userAgent(/Edge/i); var FireFox = userAgent(/firefox/i); @@ -185,23 +152,15 @@ capture: false, passive: false }; - function on(el, event, fn) { el.addEventListener(event, fn, !IE11OrLess && captureMode); } - function off(el, event, fn) { el.removeEventListener(event, fn, !IE11OrLess && captureMode); } - - function matches( - /**HTMLElement*/ - el, - /**String*/ - selector) { + function matches( /**HTMLElement*/el, /**String*/selector) { if (!selector) return; selector[0] === '>' && (selector = selector.substring(1)); - if (el) { try { if (el.matches) { @@ -215,39 +174,25 @@ return false; } } - return false; } - function getParentOrHost(el) { return el.host && el !== document && el.host.nodeType ? el.host : el.parentNode; } - - function closest( - /**HTMLElement*/ - el, - /**String*/ - selector, - /**HTMLElement*/ - ctx, includeCTX) { + function closest( /**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx, includeCTX) { if (el) { ctx = ctx || document; - do { if (selector != null && (selector[0] === '>' ? el.parentNode === ctx && matches(el, selector) : matches(el, selector)) || includeCTX && el === ctx) { return el; } - if (el === ctx) break; /* jshint boss:true */ } while (el = getParentOrHost(el)); } - return null; } - var R_SPACE = /\s+/g; - function toggleClass(el, name, state) { if (el && name) { if (el.classList) { @@ -258,10 +203,8 @@ } } } - function css(el, prop, val) { var style = el && el.style; - if (style) { if (val === void 0) { if (document.defaultView && document.defaultView.getComputedStyle) { @@ -269,68 +212,55 @@ } else if (el.currentStyle) { val = el.currentStyle; } - return prop === void 0 ? val : val[prop]; } else { if (!(prop in style) && prop.indexOf('webkit') === -1) { prop = '-webkit-' + prop; } - style[prop] = val + (typeof val === 'string' ? '' : 'px'); } } } - function matrix(el, selfOnly) { var appliedTransforms = ''; - if (typeof el === 'string') { appliedTransforms = el; } else { do { var transform = css(el, 'transform'); - if (transform && transform !== 'none') { appliedTransforms = transform + ' ' + appliedTransforms; } /* jshint boss:true */ - } while (!selfOnly && (el = el.parentNode)); } - var matrixFn = window.DOMMatrix || window.WebKitCSSMatrix || window.CSSMatrix || window.MSCSSMatrix; /*jshint -W056 */ - return matrixFn && new matrixFn(appliedTransforms); } - function find(ctx, tagName, iterator) { if (ctx) { var list = ctx.getElementsByTagName(tagName), - i = 0, - n = list.length; - + i = 0, + n = list.length; if (iterator) { for (; i < n; i++) { iterator(list[i], i); } } - return list; } - return []; } - function getWindowScrollingElement() { var scrollingElement = document.scrollingElement; - if (scrollingElement) { return scrollingElement; } else { return document.documentElement; } } + /** * Returns the "bounding client rect" of given element * @param {HTMLElement} el The element whose boundingClientRect is wanted @@ -340,12 +270,9 @@ * @param {[HTMLElement]} container The parent the element will be placed in * @return {Object} The boundingClientRect of el, with specified adjustments */ - - function getRect(el, relativeToContainingBlock, relativeToNonStaticParent, undoScale, container) { if (!el.getBoundingClientRect && el !== window) return; var elRect, top, left, bottom, right, height, width; - if (el !== window && el.parentNode && el !== getWindowScrollingElement()) { elRect = el.getBoundingClientRect(); top = elRect.top; @@ -362,17 +289,18 @@ height = window.innerHeight; width = window.innerWidth; } - if ((relativeToContainingBlock || relativeToNonStaticParent) && el !== window) { // Adjust for translate() - container = container || el.parentNode; // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) - // Not needed on <= IE11 + container = container || el.parentNode; + // solves #1123 (see: https://stackoverflow.com/a/37953806/6088312) + // Not needed on <= IE11 if (!IE11OrLess) { do { if (container && container.getBoundingClientRect && (css(container, 'transform') !== 'none' || relativeToNonStaticParent && css(container, 'position') !== 'static')) { - var containerRect = container.getBoundingClientRect(); // Set relative to edges of padding box of container + var containerRect = container.getBoundingClientRect(); + // Set relative to edges of padding box of container top -= containerRect.top + parseInt(css(container, 'border-top-width')); left -= containerRect.left + parseInt(css(container, 'border-left-width')); bottom = top + elRect.height; @@ -380,17 +308,14 @@ break; } /* jshint boss:true */ - } while (container = container.parentNode); } } - if (undoScale && el !== window) { // Adjust for scale() var elMatrix = matrix(container || el), - scaleX = elMatrix && elMatrix.a, - scaleY = elMatrix && elMatrix.d; - + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d; if (elMatrix) { top /= scaleY; left /= scaleX; @@ -400,7 +325,6 @@ right = left + width; } } - return { top: top, left: left, @@ -410,6 +334,27 @@ height: height }; } + + /** + * Returns the content rect of the element (bounding rect minus border and padding) + * @param {HTMLElement} el + */ + function getContentRect(el) { + var rect = getRect(el); + var paddingLeft = parseInt(css(el, 'padding-left')), + paddingTop = parseInt(css(el, 'padding-top')), + paddingRight = parseInt(css(el, 'padding-right')), + paddingBottom = parseInt(css(el, 'padding-bottom')); + rect.top += paddingTop + parseInt(css(el, 'border-top-width')); + rect.left += paddingLeft + parseInt(css(el, 'border-left-width')); + // Client Width/Height includes padding only + rect.width = el.clientWidth - paddingLeft - paddingRight; + rect.height = el.clientHeight - paddingTop - paddingBottom; + rect.bottom = rect.top + rect.height; + rect.right = rect.left + rect.width; + return rect; + } + /** * Checks if a side of an element is scrolled past a side of its parents * @param {HTMLElement} el The element who's side being scrolled out of view is in question @@ -417,30 +362,26 @@ * @param {String} parentSide Side of the parent in question ('top', 'left', 'right', 'bottom') * @return {HTMLElement} The parent scroll element that the el's side is scrolled past, or null if there is no such element */ - - function isScrolledPast(el, elSide, parentSide) { var parent = getParentAutoScrollElement(el, true), - elSideVal = getRect(el)[elSide]; - /* jshint boss:true */ + elSideVal = getRect(el)[elSide]; + /* jshint boss:true */ while (parent) { var parentSideVal = getRect(parent)[parentSide], - visible = void 0; - + visible = void 0; if (parentSide === 'top' || parentSide === 'left') { visible = elSideVal >= parentSideVal; } else { visible = elSideVal <= parentSideVal; } - if (!visible) return parent; if (parent === getWindowScrollingElement()) break; parent = getParentAutoScrollElement(parent, false); } - return false; } + /** * Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) * and non-draggable elements @@ -449,44 +390,36 @@ * @param {Object} options Parent Sortable's options * @return {HTMLElement} The child at index childNum, or null if not found */ - - function getChild(el, childNum, options, includeDragEl) { var currentChild = 0, - i = 0, - children = el.children; - + i = 0, + children = el.children; while (i < children.length) { if (children[i].style.display !== 'none' && children[i] !== Sortable.ghost && (includeDragEl || children[i] !== Sortable.dragged) && closest(children[i], options.draggable, el, false)) { if (currentChild === childNum) { return children[i]; } - currentChild++; } - i++; } - return null; } + /** * Gets the last child in the el, ignoring ghostEl or invisible elements (clones) * @param {HTMLElement} el Parent element * @param {selector} selector Any other elements that should be ignored * @return {HTMLElement} The last child, ignoring ghostEl */ - - function lastChild(el, selector) { var last = el.lastElementChild; - while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { last = last.previousElementSibling; } - return last || null; } + /** * Returns the index of an element within its parent for a selected set of * elements @@ -494,81 +427,67 @@ * @param {selector} selector * @return {number} */ - - function index(el, selector) { var index = 0; - if (!el || !el.parentNode) { return -1; } - /* jshint boss:true */ - + /* jshint boss:true */ while (el = el.previousElementSibling) { if (el.nodeName.toUpperCase() !== 'TEMPLATE' && el !== Sortable.clone && (!selector || matches(el, selector))) { index++; } } - return index; } + /** * Returns the scroll offset of the given element, added with all the scroll offsets of parent elements. * The value is returned in real pixels. * @param {HTMLElement} el * @return {Array} Offsets in the format of [left, top] */ - - function getRelativeScrollOffset(el) { var offsetLeft = 0, - offsetTop = 0, - winScroller = getWindowScrollingElement(); - + offsetTop = 0, + winScroller = getWindowScrollingElement(); if (el) { do { var elMatrix = matrix(el), - scaleX = elMatrix.a, - scaleY = elMatrix.d; + scaleX = elMatrix.a, + scaleY = elMatrix.d; offsetLeft += el.scrollLeft * scaleX; offsetTop += el.scrollTop * scaleY; } while (el !== winScroller && (el = el.parentNode)); } - return [offsetLeft, offsetTop]; } + /** * Returns the index of the object within the given array * @param {Array} arr Array that may or may not hold the object * @param {Object} obj An object that has a key-value pair unique to and identical to a key-value pair in the object you want to find * @return {Number} The index of the object in the array, or -1 */ - - function indexOfObject(arr, obj) { for (var i in arr) { if (!arr.hasOwnProperty(i)) continue; - for (var key in obj) { if (obj.hasOwnProperty(key) && obj[key] === arr[i][key]) return Number(i); } } - return -1; } - function getParentAutoScrollElement(el, includeSelf) { // skip to window if (!el || !el.getBoundingClientRect) return getWindowScrollingElement(); var elem = el; var gotSelf = false; - do { // we don't need to get elem css if it isn't even overflowing in the first place (performance) if (elem.clientWidth < elem.scrollWidth || elem.clientHeight < elem.scrollHeight) { var elemCSS = css(elem); - if (elem.clientWidth < elem.scrollWidth && (elemCSS.overflowX == 'auto' || elemCSS.overflowX == 'scroll') || elem.clientHeight < elem.scrollHeight && (elemCSS.overflowY == 'auto' || elemCSS.overflowY == 'scroll')) { if (!elem.getBoundingClientRect || elem === document.body) return getWindowScrollingElement(); if (gotSelf || includeSelf) return elem; @@ -576,12 +495,9 @@ } } /* jshint boss:true */ - } while (elem = elem.parentNode); - return getWindowScrollingElement(); } - function extend(dst, src) { if (dst && src) { for (var key in src) { @@ -590,49 +506,39 @@ } } } - return dst; } - function isRectEqual(rect1, rect2) { return Math.round(rect1.top) === Math.round(rect2.top) && Math.round(rect1.left) === Math.round(rect2.left) && Math.round(rect1.height) === Math.round(rect2.height) && Math.round(rect1.width) === Math.round(rect2.width); } - var _throttleTimeout; - function throttle(callback, ms) { return function () { if (!_throttleTimeout) { var args = arguments, - _this = this; - + _this = this; if (args.length === 1) { callback.call(_this, args[0]); } else { callback.apply(_this, args); } - _throttleTimeout = setTimeout(function () { _throttleTimeout = void 0; }, ms); } }; } - function cancelThrottle() { clearTimeout(_throttleTimeout); _throttleTimeout = void 0; } - function scrollBy(el, x, y) { el.scrollLeft += x; el.scrollTop += y; } - function clone(el) { var Polymer = window.Polymer; var $ = window.jQuery || window.Zepto; - if (Polymer && Polymer.dom) { return Polymer.dom(el).cloneNode(true); } else if ($) { @@ -641,7 +547,6 @@ return el.cloneNode(true); } } - function setRect(el, rect) { css(el, 'position', 'absolute'); css(el, 'top', rect.top); @@ -649,7 +554,6 @@ css(el, 'width', rect.width); css(el, 'height', rect.height); } - function unsetRect(el) { css(el, 'position', ''); css(el, 'top', ''); @@ -657,12 +561,11 @@ css(el, 'width', ''); css(el, 'height', ''); } - var expando = 'Sortable' + new Date().getTime(); function AnimationStateManager() { var animationStates = [], - animationCallbackId; + animationCallbackId; return { captureAnimationState: function captureAnimationState() { animationStates = []; @@ -674,19 +577,16 @@ target: child, rect: getRect(child) }); + var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); - var fromRect = _objectSpread2({}, animationStates[animationStates.length - 1].rect); // If animating: compensate for current animation - - + // If animating: compensate for current animation if (child.thisAnimationDuration) { var childMatrix = matrix(child, true); - if (childMatrix) { fromRect.top -= childMatrix.f; fromRect.left -= childMatrix.e; } } - child.fromRect = fromRect; }); }, @@ -700,54 +600,47 @@ }, animateAll: function animateAll(callback) { var _this = this; - if (!this.options.animation) { clearTimeout(animationCallbackId); if (typeof callback === 'function') callback(); return; } - var animating = false, - animationTime = 0; + animationTime = 0; animationStates.forEach(function (state) { var time = 0, - target = state.target, - fromRect = target.fromRect, - toRect = getRect(target), - prevFromRect = target.prevFromRect, - prevToRect = target.prevToRect, - animatingRect = state.rect, - targetMatrix = matrix(target, true); - + target = state.target, + fromRect = target.fromRect, + toRect = getRect(target), + prevFromRect = target.prevFromRect, + prevToRect = target.prevToRect, + animatingRect = state.rect, + targetMatrix = matrix(target, true); if (targetMatrix) { // Compensate for current animation toRect.top -= targetMatrix.f; toRect.left -= targetMatrix.e; } - target.toRect = toRect; - if (target.thisAnimationDuration) { // Could also check if animatingRect is between fromRect and toRect - if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && // Make sure animatingRect is on line between toRect & fromRect + if (isRectEqual(prevFromRect, toRect) && !isRectEqual(fromRect, toRect) && + // Make sure animatingRect is on line between toRect & fromRect (animatingRect.top - toRect.top) / (animatingRect.left - toRect.left) === (fromRect.top - toRect.top) / (fromRect.left - toRect.left)) { // If returning to same place as started from animation and on same axis time = calculateRealTime(animatingRect, prevFromRect, prevToRect, _this.options); } - } // if fromRect != toRect: animate - + } + // if fromRect != toRect: animate if (!isRectEqual(toRect, fromRect)) { target.prevFromRect = fromRect; target.prevToRect = toRect; - if (!time) { time = _this.options.animation; } - _this.animate(target, animatingRect, toRect, time); } - if (time) { animating = true; animationTime = Math.max(animationTime, time); @@ -763,7 +656,6 @@ } }); clearTimeout(animationCallbackId); - if (!animating) { if (typeof callback === 'function') callback(); } else { @@ -771,7 +663,6 @@ if (typeof callback === 'function') callback(); }, animationTime); } - animationStates = []; }, animate: function animate(target, currentRect, toRect, duration) { @@ -779,10 +670,10 @@ css(target, 'transition', ''); css(target, 'transform', ''); var elMatrix = matrix(this.el), - scaleX = elMatrix && elMatrix.a, - scaleY = elMatrix && elMatrix.d, - translateX = (currentRect.left - toRect.left) / (scaleX || 1), - translateY = (currentRect.top - toRect.top) / (scaleY || 1); + scaleX = elMatrix && elMatrix.a, + scaleY = elMatrix && elMatrix.d, + translateX = (currentRect.left - toRect.left) / (scaleX || 1), + translateY = (currentRect.top - toRect.top) / (scaleY || 1); target.animatingX = !!translateX; target.animatingY = !!translateY; css(target, 'transform', 'translate3d(' + translateX + 'px,' + translateY + 'px,0)'); @@ -802,11 +693,9 @@ } }; } - function repaint(target) { return target.offsetWidth; } - function calculateRealTime(animatingRect, fromRect, toRect, options) { return Math.sqrt(Math.pow(fromRect.top - animatingRect.top, 2) + Math.pow(fromRect.left - animatingRect.left, 2)) / Math.sqrt(Math.pow(fromRect.top - toRect.top, 2) + Math.pow(fromRect.left - toRect.left, 2)) * options.animation; } @@ -823,7 +712,6 @@ plugin[option] = defaults[option]; } } - plugins.forEach(function (p) { if (p.pluginName === plugin.pluginName) { throw "Sortable: Cannot mount plugin ".concat(plugin.pluginName, " more than once"); @@ -833,25 +721,22 @@ }, pluginEvent: function pluginEvent(eventName, sortable, evt) { var _this = this; - this.eventCanceled = false; - evt.cancel = function () { _this.eventCanceled = true; }; - var eventNameGlobal = eventName + 'Global'; plugins.forEach(function (plugin) { - if (!sortable[plugin.pluginName]) return; // Fire global events if it exists in this sortable - + if (!sortable[plugin.pluginName]) return; + // Fire global events if it exists in this sortable if (sortable[plugin.pluginName][eventNameGlobal]) { sortable[plugin.pluginName][eventNameGlobal](_objectSpread2({ sortable: sortable }, evt)); - } // Only fire plugin event if plugin is enabled in this sortable, - // and plugin has event defined - + } + // Only fire plugin event if plugin is enabled in this sortable, + // and plugin has event defined if (sortable.options[plugin.pluginName] && sortable[plugin.pluginName][eventName]) { sortable[plugin.pluginName][eventName](_objectSpread2({ sortable: sortable @@ -866,15 +751,14 @@ var initialized = new plugin(sortable, el, sortable.options); initialized.sortable = sortable; initialized.options = sortable.options; - sortable[pluginName] = initialized; // Add default options from plugin + sortable[pluginName] = initialized; + // Add default options from plugin _extends(defaults, initialized.defaults); }); - for (var option in sortable.options) { if (!sortable.options.hasOwnProperty(option)) continue; var modified = this.modifyOption(sortable, option, sortable.options[option]); - if (typeof modified !== 'undefined') { sortable.options[option] = modified; } @@ -884,7 +768,6 @@ var eventProperties = {}; plugins.forEach(function (plugin) { if (typeof plugin.eventProperties !== 'function') return; - _extends(eventProperties, plugin.eventProperties.call(sortable[plugin.pluginName], name)); }); return eventProperties; @@ -893,8 +776,9 @@ var modifiedValue; plugins.forEach(function (plugin) { // Plugin must exist on the Sortable - if (!sortable[plugin.pluginName]) return; // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin + if (!sortable[plugin.pluginName]) return; + // If static option listener exists for this option, call in the context of the Sortable's instance of this plugin if (plugin.optionListeners && typeof plugin.optionListeners[name] === 'function') { modifiedValue = plugin.optionListeners[name].call(sortable[plugin.pluginName], value); } @@ -905,25 +789,25 @@ function dispatchEvent(_ref) { var sortable = _ref.sortable, - rootEl = _ref.rootEl, - name = _ref.name, - targetEl = _ref.targetEl, - cloneEl = _ref.cloneEl, - toEl = _ref.toEl, - fromEl = _ref.fromEl, - oldIndex = _ref.oldIndex, - newIndex = _ref.newIndex, - oldDraggableIndex = _ref.oldDraggableIndex, - newDraggableIndex = _ref.newDraggableIndex, - originalEvent = _ref.originalEvent, - putSortable = _ref.putSortable, - extraEventProperties = _ref.extraEventProperties; + rootEl = _ref.rootEl, + name = _ref.name, + targetEl = _ref.targetEl, + cloneEl = _ref.cloneEl, + toEl = _ref.toEl, + fromEl = _ref.fromEl, + oldIndex = _ref.oldIndex, + newIndex = _ref.newIndex, + oldDraggableIndex = _ref.oldDraggableIndex, + newDraggableIndex = _ref.newDraggableIndex, + originalEvent = _ref.originalEvent, + putSortable = _ref.putSortable, + extraEventProperties = _ref.extraEventProperties; sortable = sortable || rootEl && rootEl[expando]; if (!sortable) return; var evt, - options = sortable.options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); // Support for new CustomEvent feature - + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + // Support for new CustomEvent feature if (window.CustomEvent && !IE11OrLess && !Edge) { evt = new CustomEvent(name, { bubbles: true, @@ -933,7 +817,6 @@ evt = document.createEvent('Event'); evt.initEvent(name, true, true); } - evt.to = toEl || rootEl; evt.from = fromEl || rootEl; evt.item = targetEl || rootEl; @@ -944,29 +827,23 @@ evt.newDraggableIndex = newDraggableIndex; evt.originalEvent = originalEvent; evt.pullMode = putSortable ? putSortable.lastPutMode : undefined; - var allEventProperties = _objectSpread2(_objectSpread2({}, extraEventProperties), PluginManager.getEventProperties(name, sortable)); - for (var option in allEventProperties) { evt[option] = allEventProperties[option]; } - if (rootEl) { rootEl.dispatchEvent(evt); } - if (options[onName]) { options[onName].call(sortable, evt); } } var _excluded = ["evt"]; - var pluginEvent = function pluginEvent(eventName, sortable) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, - originalEvent = _ref.evt, - data = _objectWithoutProperties(_ref, _excluded); - + originalEvent = _ref.evt, + data = _objectWithoutProperties(_ref, _excluded); PluginManager.pluginEvent.bind(Sortable)(eventName, sortable, _objectSpread2({ dragEl: dragEl, parentEl: parentEl, @@ -1001,7 +878,6 @@ } }, data)); }; - function _dispatchEvent(info) { dispatchEvent(_objectSpread2({ putSortable: putSortable, @@ -1014,62 +890,61 @@ newDraggableIndex: newDraggableIndex }, info)); } - var dragEl, - parentEl, - ghostEl, - rootEl, - nextEl, - lastDownEl, - cloneEl, - cloneHidden, - oldIndex, - newIndex, - oldDraggableIndex, - newDraggableIndex, - activeGroup, - putSortable, - awaitingDragStarted = false, - ignoreNextClick = false, - sortables = [], - tapEvt, - touchEvt, - lastDx, - lastDy, - tapDistanceLeft, - tapDistanceTop, - moved, - lastTarget, - lastDirection, - pastFirstInvertThresh = false, - isCircumstantialInvert = false, - targetMoveDistance, - // For positioning ghost absolutely - ghostRelativeParent, - ghostRelativeParentInitialScroll = [], - // (left, top) - _silent = false, - savedInputChecked = []; - /** @const */ + parentEl, + ghostEl, + rootEl, + nextEl, + lastDownEl, + cloneEl, + cloneHidden, + oldIndex, + newIndex, + oldDraggableIndex, + newDraggableIndex, + activeGroup, + putSortable, + awaitingDragStarted = false, + ignoreNextClick = false, + sortables = [], + tapEvt, + touchEvt, + lastDx, + lastDy, + tapDistanceLeft, + tapDistanceTop, + moved, + lastTarget, + lastDirection, + pastFirstInvertThresh = false, + isCircumstantialInvert = false, + targetMoveDistance, + // For positioning ghost absolutely + ghostRelativeParent, + ghostRelativeParentInitialScroll = [], + // (left, top) + + _silent = false, + savedInputChecked = []; + /** @const */ var documentExists = typeof document !== 'undefined', - PositionGhostAbsolutely = IOS, - CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', - // This will not pass for IE9, because IE9 DnD only works on anchors - supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), - supportCssPointerEvents = function () { - if (!documentExists) return; // false when <= IE11 - - if (IE11OrLess) { - return false; - } - - var el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - }(), - _detectDirection = function _detectDirection(el, options) { - var elCSS = css(el), + PositionGhostAbsolutely = IOS, + CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float', + // This will not pass for IE9, because IE9 DnD only works on anchors + supportDraggable = documentExists && !ChromeForAndroid && !IOS && 'draggable' in document.createElement('div'), + supportCssPointerEvents = function () { + if (!documentExists) return; + // false when <= IE11 + if (IE11OrLess) { + return false; + } + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + }(), + _detectDirection = function _detectDirection(el, options) { + var elCSS = css(el), elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), child1 = getChild(el, 0, options), child2 = getChild(el, 1, options), @@ -1077,103 +952,93 @@ secondChildCSS = child2 && css(child2), firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; - - if (elCSS.display === 'flex') { - return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; - } - - if (elCSS.display === 'grid') { - return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; - } - - if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { - var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; - return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; - } - - return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; - }, - _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { - var dragElS1Opp = vertical ? dragRect.left : dragRect.top, + if (elCSS.display === 'flex') { + return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; + } + if (elCSS.display === 'grid') { + return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; + } + if (child1 && firstChildCSS["float"] && firstChildCSS["float"] !== 'none') { + var touchingSideChild2 = firstChildCSS["float"] === 'left' ? 'left' : 'right'; + return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; + } + return child1 && (firstChildCSS.display === 'block' || firstChildCSS.display === 'flex' || firstChildCSS.display === 'table' || firstChildCSS.display === 'grid' || firstChildWidth >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && firstChildWidth + secondChildWidth > elWidth) ? 'vertical' : 'horizontal'; + }, + _dragElInRowColumn = function _dragElInRowColumn(dragRect, targetRect, vertical) { + var dragElS1Opp = vertical ? dragRect.left : dragRect.top, dragElS2Opp = vertical ? dragRect.right : dragRect.bottom, dragElOppLength = vertical ? dragRect.width : dragRect.height, targetS1Opp = vertical ? targetRect.left : targetRect.top, targetS2Opp = vertical ? targetRect.right : targetRect.bottom, targetOppLength = vertical ? targetRect.width : targetRect.height; - return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; - }, - - /** - * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. - * @param {Number} x X position - * @param {Number} y Y position - * @return {HTMLElement} Element of the first found nearest Sortable - */ - _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { - var ret; - sortables.some(function (sortable) { - var threshold = sortable[expando].options.emptyInsertThreshold; - if (!threshold || lastChild(sortable)) return; - var rect = getRect(sortable), + return dragElS1Opp === targetS1Opp || dragElS2Opp === targetS2Opp || dragElS1Opp + dragElOppLength / 2 === targetS1Opp + targetOppLength / 2; + }, + /** + * Detects first nearest empty sortable to X and Y position using emptyInsertThreshold. + * @param {Number} x X position + * @param {Number} y Y position + * @return {HTMLElement} Element of the first found nearest Sortable + */ + _detectNearestEmptySortable = function _detectNearestEmptySortable(x, y) { + var ret; + sortables.some(function (sortable) { + var threshold = sortable[expando].options.emptyInsertThreshold; + if (!threshold || lastChild(sortable)) return; + var rect = getRect(sortable), insideHorizontally = x >= rect.left - threshold && x <= rect.right + threshold, insideVertically = y >= rect.top - threshold && y <= rect.bottom + threshold; - - if (insideHorizontally && insideVertically) { - return ret = sortable; - } - }); - return ret; - }, - _prepareGroup = function _prepareGroup(options) { - function toFn(value, pull) { - return function (to, from, dragEl, evt) { - var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; - - if (value == null && (pull || sameGroup)) { - // Default pull value - // Default pull and put value if same group - return true; - } else if (value == null || value === false) { - return false; - } else if (pull && value === 'clone') { - return value; - } else if (typeof value === 'function') { - return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); - } else { - var otherGroup = (pull ? to : from).options.group.name; - return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + if (insideHorizontally && insideVertically) { + return ret = sortable; } - }; - } - - var group = {}; - var originalGroup = options.group; - - if (!originalGroup || _typeof(originalGroup) != 'object') { - originalGroup = { - name: originalGroup - }; - } - - group.name = originalGroup.name; - group.checkPull = toFn(originalGroup.pull, true); - group.checkPut = toFn(originalGroup.put); - group.revertClone = originalGroup.revertClone; - options.group = group; - }, - _hideGhostForTarget = function _hideGhostForTarget() { - if (!supportCssPointerEvents && ghostEl) { - css(ghostEl, 'display', 'none'); - } - }, - _unhideGhostForTarget = function _unhideGhostForTarget() { - if (!supportCssPointerEvents && ghostEl) { - css(ghostEl, 'display', ''); - } - }; // #1184 fix - Prevent click event on fallback if dragged but item not changed position - + }); + return ret; + }, + _prepareGroup = function _prepareGroup(options) { + function toFn(value, pull) { + return function (to, from, dragEl, evt) { + var sameGroup = to.options.group.name && from.options.group.name && to.options.group.name === from.options.group.name; + if (value == null && (pull || sameGroup)) { + // Default pull value + // Default pull and put value if same group + return true; + } else if (value == null || value === false) { + return false; + } else if (pull && value === 'clone') { + return value; + } else if (typeof value === 'function') { + return toFn(value(to, from, dragEl, evt), pull)(to, from, dragEl, evt); + } else { + var otherGroup = (pull ? to : from).options.group.name; + return value === true || typeof value === 'string' && value === otherGroup || value.join && value.indexOf(otherGroup) > -1; + } + }; + } + var group = {}; + var originalGroup = options.group; + if (!originalGroup || _typeof(originalGroup) != 'object') { + originalGroup = { + name: originalGroup + }; + } + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + options.group = group; + }, + _hideGhostForTarget = function _hideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', 'none'); + } + }, + _unhideGhostForTarget = function _unhideGhostForTarget() { + if (!supportCssPointerEvents && ghostEl) { + css(ghostEl, 'display', ''); + } + }; - if (documentExists) { + // #1184 fix - Prevent click event on fallback if dragged but item not changed position + if (documentExists && !ChromeForAndroid) { document.addEventListener('click', function (evt) { if (ignoreNextClick) { evt.preventDefault(); @@ -1184,53 +1049,44 @@ } }, true); } - var nearestEmptyInsertDetectEvent = function nearestEmptyInsertDetectEvent(evt) { if (dragEl) { evt = evt.touches ? evt.touches[0] : evt; - var nearest = _detectNearestEmptySortable(evt.clientX, evt.clientY); - if (nearest) { // Create imitation event var event = {}; - for (var i in evt) { if (evt.hasOwnProperty(i)) { event[i] = evt[i]; } } - event.target = event.rootEl = nearest; event.preventDefault = void 0; event.stopPropagation = void 0; - nearest[expando]._onDragOver(event); } } }; - var _checkOutsideTargetEl = function _checkOutsideTargetEl(evt) { if (dragEl) { dragEl.parentNode[expando]._isOutsideThisEl(evt.target); } }; + /** * @class Sortable * @param {HTMLElement} el * @param {Object} [options] */ - - function Sortable(el, options) { if (!(el && el.nodeType && el.nodeType === 1)) { throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); } - this.el = el; // root element + this.options = options = _extends({}, options); - this.options = options = _extends({}, options); // Export instance - + // Export instance el[expando] = this; var defaults = { group: null, @@ -1277,52 +1133,48 @@ supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari, emptyInsertThreshold: 5 }; - PluginManager.initializePlugins(this, el, defaults); // Set default options + PluginManager.initializePlugins(this, el, defaults); + // Set default options for (var name in defaults) { !(name in options) && (options[name] = defaults[name]); } + _prepareGroup(options); - _prepareGroup(options); // Bind all private methods - - + // Bind all private methods for (var fn in this) { if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { this[fn] = this[fn].bind(this); } - } // Setup drag mode - + } + // Setup drag mode this.nativeDraggable = options.forceFallback ? false : supportDraggable; - if (this.nativeDraggable) { // Touch start threshold cannot be greater than the native dragstart threshold this.options.touchStartThreshold = 1; - } // Bind events - + } + // Bind events if (options.supportPointer) { on(el, 'pointerdown', this._onTapStart); } else { on(el, 'mousedown', this._onTapStart); on(el, 'touchstart', this._onTapStart); } - if (this.nativeDraggable) { on(el, 'dragover', this); on(el, 'dragenter', this); } + sortables.push(this.el); - sortables.push(this.el); // Restore sorting - - options.store && options.store.get && this.sort(options.store.get(this) || []); // Add animation state manager + // Restore sorting + options.store && options.store.get && this.sort(options.store.get(this) || []); + // Add animation state manager _extends(this, AnimationStateManager()); } - - Sortable.prototype = - /** @lends Sortable.prototype */ - { + Sortable.prototype = /** @lends Sortable.prototype */{ constructor: Sortable, _isOutsideThisEl: function _isOutsideThisEl(target) { if (!this.el.contains(target) && target !== this.el) { @@ -1332,57 +1184,50 @@ _getDirection: function _getDirection(evt, target) { return typeof this.options.direction === 'function' ? this.options.direction.call(this, evt, target, dragEl) : this.options.direction; }, - _onTapStart: function _onTapStart( - /** Event|TouchEvent */ - evt) { + _onTapStart: function _onTapStart( /** Event|TouchEvent */evt) { if (!evt.cancelable) return; - var _this = this, - el = this.el, - options = this.options, - preventOnFilter = options.preventOnFilter, - type = evt.type, - touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, - target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, - filter = options.filter; - - _saveInputCheckedState(el); // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. - - + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0] || evt.pointerType && evt.pointerType === 'touch' && evt, + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0] || evt.composedPath && evt.composedPath()[0]) || target, + filter = options.filter; + _saveInputCheckedState(el); + + // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. if (dragEl) { return; } - if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { return; // only left button and enabled - } // cancel dnd if original target is content editable - + } + // cancel dnd if original target is content editable if (originalTarget.isContentEditable) { return; - } // Safari ignores further event handling after mousedown - + } + // Safari ignores further event handling after mousedown if (!this.nativeDraggable && Safari && target && target.tagName.toUpperCase() === 'SELECT') { return; } - target = closest(target, options.draggable, el, false); - if (target && target.animated) { return; } - if (lastDownEl === target) { // Ignoring duplicate `down` return; - } // Get the index of the dragged element within its parent - + } + // Get the index of the dragged element within its parent oldIndex = index(target); - oldDraggableIndex = index(target, options.draggable); // Check filter + oldDraggableIndex = index(target, options.draggable); + // Check filter if (typeof filter === 'function') { if (filter.call(this, evt, target, this)) { _dispatchEvent({ @@ -1393,7 +1238,6 @@ toEl: el, fromEl: el }); - pluginEvent('filter', _this, { evt: evt }); @@ -1403,7 +1247,6 @@ } else if (filter) { filter = filter.split(',').some(function (criteria) { criteria = closest(originalTarget, criteria.trim(), el, false); - if (criteria) { _dispatchEvent({ sortable: _this, @@ -1413,40 +1256,30 @@ fromEl: el, toEl: el }); - pluginEvent('filter', _this, { evt: evt }); return true; } }); - if (filter) { preventOnFilter && evt.cancelable && evt.preventDefault(); return; // cancel dnd } } - if (options.handle && !closest(originalTarget, options.handle, el, false)) { return; - } // Prepare `dragstart` - + } + // Prepare `dragstart` this._prepareDragStart(evt, touch, target); }, - _prepareDragStart: function _prepareDragStart( - /** Event */ - evt, - /** Touch */ - touch, - /** HTMLElement */ - target) { + _prepareDragStart: function _prepareDragStart( /** Event */evt, /** Touch */touch, /** HTMLElement */target) { var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; if (target && !dragEl && target.parentNode === el) { var dragRect = getRect(target); rootEl = el; @@ -1466,41 +1299,36 @@ this._lastX = (touch || evt).clientX; this._lastY = (touch || evt).clientY; dragEl.style['will-change'] = 'all'; - dragStartFn = function dragStartFn() { pluginEvent('delayEnded', _this, { evt: evt }); - if (Sortable.eventCanceled) { _this._onDrop(); - return; - } // Delayed drag has been triggered + } + // Delayed drag has been triggered // we can re-enable the events: touchmove/mousemove - - _this._disableDelayedDragEvents(); - if (!FireFox && _this.nativeDraggable) { dragEl.draggable = true; - } // Bind the events: dragstart/dragend - - - _this._triggerDragStart(evt, touch); // Drag start event + } + // Bind the events: dragstart/dragend + _this._triggerDragStart(evt, touch); + // Drag start event _dispatchEvent({ sortable: _this, name: 'choose', originalEvent: evt - }); // Chosen item - + }); + // Chosen item toggleClass(dragEl, options.chosenClass, true); - }; // Disable "draggable" - + }; + // Disable "draggable" options.ignore.split(',').forEach(function (criteria) { find(dragEl, criteria.trim(), _disableDraggable); }); @@ -1509,27 +1337,26 @@ on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); on(ownerDocument, 'mouseup', _this._onDrop); on(ownerDocument, 'touchend', _this._onDrop); - on(ownerDocument, 'touchcancel', _this._onDrop); // Make dragEl draggable (must be before delay for FireFox) + on(ownerDocument, 'touchcancel', _this._onDrop); + // Make dragEl draggable (must be before delay for FireFox) if (FireFox && this.nativeDraggable) { this.options.touchStartThreshold = 4; dragEl.draggable = true; } - pluginEvent('delayStart', this, { evt: evt - }); // Delay is impossible for native DnD in Edge or IE + }); + // Delay is impossible for native DnD in Edge or IE if (options.delay && (!options.delayOnTouchOnly || touch) && (!this.nativeDraggable || !(Edge || IE11OrLess))) { if (Sortable.eventCanceled) { this._onDrop(); - return; - } // If the user moves the pointer or let go the click or touch + } + // If the user moves the pointer or let go the click or touch // before the delay has been reached: // disable the delayed drag - - on(ownerDocument, 'mouseup', _this._disableDelayedDrag); on(ownerDocument, 'touchend', _this._disableDelayedDrag); on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); @@ -1542,11 +1369,8 @@ } } }, - _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( - /** TouchEvent|PointerEvent **/ - e) { + _delayedDragTouchMoveHandler: function _delayedDragTouchMoveHandler( /** TouchEvent|PointerEvent **/e) { var touch = e.touches ? e.touches[0] : e; - if (Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) >= Math.floor(this.options.touchStartThreshold / (this.nativeDraggable && window.devicePixelRatio || 1))) { this._disableDelayedDrag(); } @@ -1554,7 +1378,6 @@ _disableDelayedDrag: function _disableDelayedDrag() { dragEl && _disableDraggable(dragEl); clearTimeout(this._dragStartTimer); - this._disableDelayedDragEvents(); }, _disableDelayedDragEvents: function _disableDelayedDragEvents() { @@ -1566,13 +1389,8 @@ off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); }, - _triggerDragStart: function _triggerDragStart( - /** Event */ - evt, - /** Touch */ - touch) { + _triggerDragStart: function _triggerDragStart( /** Event */evt, /** Touch */touch) { touch = touch || evt.pointerType == 'touch' && evt; - if (!this.nativeDraggable || touch) { if (this.options.supportPointer) { on(document, 'pointermove', this._onTouchMove); @@ -1585,7 +1403,6 @@ on(dragEl, 'dragend', this); on(rootEl, 'dragstart', this._onDragStart); } - try { if (document.selection) { // Timeout neccessary for IE9 @@ -1598,25 +1415,23 @@ } catch (err) {} }, _dragStarted: function _dragStarted(fallback, evt) { - awaitingDragStarted = false; - if (rootEl && dragEl) { pluginEvent('dragStarted', this, { evt: evt }); - if (this.nativeDraggable) { on(document, 'dragover', _checkOutsideTargetEl); } + var options = this.options; - var options = this.options; // Apply effect - + // Apply effect !fallback && toggleClass(dragEl, options.dragClass, false); toggleClass(dragEl, options.ghostClass, true); Sortable.active = this; - fallback && this._appendGhost(); // Drag start event + fallback && this._appendGhost(); + // Drag start event _dispatchEvent({ sortable: this, name: 'start', @@ -1630,20 +1445,15 @@ if (touchEvt) { this._lastX = touchEvt.clientX; this._lastY = touchEvt.clientY; - _hideGhostForTarget(); - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); var parent = target; - while (target && target.shadowRoot) { target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); if (target === parent) break; parent = target; } - dragEl.parentNode[expando]._isOutsideThisEl(target); - if (parent) { do { if (parent[expando]) { @@ -1654,44 +1464,37 @@ target: target, rootEl: parent }); - if (inserted && !this.options.dragoverBubble) { break; } } - target = parent; // store last element } - /* jshint boss:true */ - while (parent = parent.parentNode); + /* jshint boss:true */ while (parent = parent.parentNode); } - _unhideGhostForTarget(); } }, - _onTouchMove: function _onTouchMove( - /**TouchEvent*/ - evt) { + _onTouchMove: function _onTouchMove( /**TouchEvent*/evt) { if (tapEvt) { var options = this.options, - fallbackTolerance = options.fallbackTolerance, - fallbackOffset = options.fallbackOffset, - touch = evt.touches ? evt.touches[0] : evt, - ghostMatrix = ghostEl && matrix(ghostEl, true), - scaleX = ghostEl && ghostMatrix && ghostMatrix.a, - scaleY = ghostEl && ghostMatrix && ghostMatrix.d, - relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), - dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), - dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); // only set the status to dragging, when we are actually dragging - + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + ghostMatrix = ghostEl && matrix(ghostEl, true), + scaleX = ghostEl && ghostMatrix && ghostMatrix.a, + scaleY = ghostEl && ghostMatrix && ghostMatrix.d, + relativeScrollOffset = PositionGhostAbsolutely && ghostRelativeParent && getRelativeScrollOffset(ghostRelativeParent), + dx = (touch.clientX - tapEvt.clientX + fallbackOffset.x) / (scaleX || 1) + (relativeScrollOffset ? relativeScrollOffset[0] - ghostRelativeParentInitialScroll[0] : 0) / (scaleX || 1), + dy = (touch.clientY - tapEvt.clientY + fallbackOffset.y) / (scaleY || 1) + (relativeScrollOffset ? relativeScrollOffset[1] - ghostRelativeParentInitialScroll[1] : 0) / (scaleY || 1); + + // only set the status to dragging, when we are actually dragging if (!Sortable.active && !awaitingDragStarted) { if (fallbackTolerance && Math.max(Math.abs(touch.clientX - this._lastX), Math.abs(touch.clientY - this._lastY)) < fallbackTolerance) { return; } - this._onDragStart(evt, true); } - if (ghostEl) { if (ghostMatrix) { ghostMatrix.e += dx - (lastDx || 0); @@ -1706,7 +1509,6 @@ f: dy }; } - var cssMatrix = "matrix(".concat(ghostMatrix.a, ",").concat(ghostMatrix.b, ",").concat(ghostMatrix.c, ",").concat(ghostMatrix.d, ",").concat(ghostMatrix.e, ",").concat(ghostMatrix.f, ")"); css(ghostEl, 'webkitTransform', cssMatrix); css(ghostEl, 'mozTransform', cssMatrix); @@ -1716,7 +1518,6 @@ lastDy = dy; touchEvt = touch; } - evt.cancelable && evt.preventDefault(); } }, @@ -1725,17 +1526,16 @@ // Not being adjusted for if (!ghostEl) { var container = this.options.fallbackOnBody ? document.body : rootEl, - rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), - options = this.options; // Position absolutely + rect = getRect(dragEl, true, PositionGhostAbsolutely, true, container), + options = this.options; + // Position absolutely if (PositionGhostAbsolutely) { // Get relatively positioned parent ghostRelativeParent = container; - while (css(ghostRelativeParent, 'position') === 'static' && css(ghostRelativeParent, 'transform') === 'none' && ghostRelativeParent !== document) { ghostRelativeParent = ghostRelativeParent.parentNode; } - if (ghostRelativeParent !== document.body && ghostRelativeParent !== document.documentElement) { if (ghostRelativeParent === document) ghostRelativeParent = getWindowScrollingElement(); rect.top += ghostRelativeParent.scrollTop; @@ -1743,10 +1543,8 @@ } else { ghostRelativeParent = getWindowScrollingElement(); } - ghostRelativeParentInitialScroll = getRelativeScrollOffset(ghostRelativeParent); } - ghostEl = dragEl.cloneNode(true); toggleClass(ghostEl, options.ghostClass, false); toggleClass(ghostEl, options.fallbackClass, true); @@ -1764,61 +1562,50 @@ css(ghostEl, 'zIndex', '100000'); css(ghostEl, 'pointerEvents', 'none'); Sortable.ghost = ghostEl; - container.appendChild(ghostEl); // Set transform-origin + container.appendChild(ghostEl); + // Set transform-origin css(ghostEl, 'transform-origin', tapDistanceLeft / parseInt(ghostEl.style.width) * 100 + '% ' + tapDistanceTop / parseInt(ghostEl.style.height) * 100 + '%'); } }, - _onDragStart: function _onDragStart( - /**Event*/ - evt, - /**boolean*/ - fallback) { + _onDragStart: function _onDragStart( /**Event*/evt, /**boolean*/fallback) { var _this = this; - var dataTransfer = evt.dataTransfer; var options = _this.options; pluginEvent('dragStart', this, { evt: evt }); - if (Sortable.eventCanceled) { this._onDrop(); - return; } - pluginEvent('setupClone', this); - if (!Sortable.eventCanceled) { cloneEl = clone(dragEl); + cloneEl.removeAttribute("id"); cloneEl.draggable = false; cloneEl.style['will-change'] = ''; - this._hideClone(); - toggleClass(cloneEl, this.options.chosenClass, false); Sortable.clone = cloneEl; - } // #1143: IFrame support workaround - + } + // #1143: IFrame support workaround _this.cloneId = _nextTick(function () { pluginEvent('clone', _this); if (Sortable.eventCanceled) return; - if (!_this.options.removeCloneOnHide) { rootEl.insertBefore(cloneEl, dragEl); } - _this._hideClone(); - _dispatchEvent({ sortable: _this, name: 'clone' }); }); - !fallback && toggleClass(dragEl, options.dragClass, true); // Set proper drop events + !fallback && toggleClass(dragEl, options.dragClass, true); + // Set proper drop events if (fallback) { ignoreNextClick = true; _this._loopId = setInterval(_this._emulateDragOver, 50); @@ -1827,47 +1614,40 @@ off(document, 'mouseup', _this._onDrop); off(document, 'touchend', _this._onDrop); off(document, 'touchcancel', _this._onDrop); - if (dataTransfer) { dataTransfer.effectAllowed = 'move'; options.setData && options.setData.call(_this, dataTransfer, dragEl); } + on(document, 'drop', _this); - on(document, 'drop', _this); // #1276 fix: - + // #1276 fix: css(dragEl, 'transform', 'translateZ(0)'); } - awaitingDragStarted = true; _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); on(document, 'selectstart', _this); moved = true; - if (Safari) { css(document.body, 'user-select', 'none'); } }, // Returns true - if no further action is needed (either inserted or another condition) - _onDragOver: function _onDragOver( - /**Event*/ - evt) { + _onDragOver: function _onDragOver( /**Event*/evt) { var el = this.el, - target = evt.target, - dragRect, - targetRect, - revert, - options = this.options, - group = options.group, - activeSortable = Sortable.active, - isOwner = activeGroup === group, - canSort = options.sort, - fromSortable = putSortable || activeSortable, - vertical, - _this = this, - completedFired = false; - + target = evt.target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = activeGroup === group, + canSort = options.sort, + fromSortable = putSortable || activeSortable, + vertical, + _this = this, + completedFired = false; if (_silent) return; - function dragOverEvent(name, extra) { pluginEvent(name, _this, _objectSpread2({ evt: evt, @@ -1885,25 +1665,22 @@ }, changed: changed }, extra)); - } // Capture animation state - + } + // Capture animation state function capture() { dragOverEvent('dragOverAnimationCapture'); - _this.captureAnimationState(); - if (_this !== fromSortable) { fromSortable.captureAnimationState(); } - } // Return invocation when dragEl is inserted (or completed) - + } + // Return invocation when dragEl is inserted (or completed) function completed(insertion) { dragOverEvent('dragOverCompleted', { insertion: insertion }); - if (insertion) { // Clones must be hidden before folding animation to capture dragRectAbsolute properly if (isOwner) { @@ -1911,57 +1688,51 @@ } else { activeSortable._showClone(_this); } - if (_this !== fromSortable) { // Set ghost class to new sortable's ghost class toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : activeSortable.options.ghostClass, false); toggleClass(dragEl, options.ghostClass, true); } - if (putSortable !== _this && _this !== Sortable.active) { putSortable = _this; } else if (_this === Sortable.active && putSortable) { putSortable = null; - } // Animation - + } + // Animation if (fromSortable === _this) { _this._ignoreWhileAnimating = target; } - _this.animateAll(function () { dragOverEvent('dragOverAnimationComplete'); _this._ignoreWhileAnimating = null; }); - if (_this !== fromSortable) { fromSortable.animateAll(); fromSortable._ignoreWhileAnimating = null; } - } // Null lastTarget if it is not inside a previously swapped element - + } + // Null lastTarget if it is not inside a previously swapped element if (target === dragEl && !dragEl.animated || target === el && !target.animated) { lastTarget = null; - } // no bubbling and not fallback - + } + // no bubbling and not fallback if (!options.dragoverBubble && !evt.rootEl && target !== document) { - dragEl.parentNode[expando]._isOutsideThisEl(evt.target); // Do not detect for empty insert if already inserted - + dragEl.parentNode[expando]._isOutsideThisEl(evt.target); + // Do not detect for empty insert if already inserted !insertion && nearestEmptyInsertDetectEvent(evt); } - !options.dragoverBubble && evt.stopPropagation && evt.stopPropagation(); return completedFired = true; - } // Call when dragEl has been inserted - + } + // Call when dragEl has been inserted function changed() { newIndex = index(dragEl); newDraggableIndex = index(dragEl, options.draggable); - _dispatchEvent({ sortable: _this, name: 'change', @@ -1971,37 +1742,27 @@ originalEvent: evt }); } - if (evt.preventDefault !== void 0) { evt.cancelable && evt.preventDefault(); } - target = closest(target, options.draggable, el, true); dragOverEvent('dragOver'); if (Sortable.eventCanceled) return completedFired; - if (dragEl.contains(evt.target) || target.animated && target.animatingX && target.animatingY || _this._ignoreWhileAnimating === target) { return completed(false); } - ignoreNextClick = false; - if (activeSortable && !options.disabled && (isOwner ? canSort || (revert = parentEl !== rootEl) // Reverting item into the original list : putSortable === this || (this.lastPutMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && group.checkPut(this, activeSortable, dragEl, evt))) { vertical = this._getDirection(evt, target) === 'vertical'; dragRect = getRect(dragEl); dragOverEvent('dragOverValid'); if (Sortable.eventCanceled) return completedFired; - if (revert) { parentEl = rootEl; // actualization - capture(); - this._hideClone(); - dragOverEvent('revert'); - if (!Sortable.eventCanceled) { if (nextEl) { rootEl.insertBefore(dragEl, nextEl); @@ -2009,31 +1770,32 @@ rootEl.appendChild(dragEl); } } - return completed(true); } - var elLastChild = lastChild(el, options.draggable); - if (!elLastChild || _ghostIsLast(evt, vertical, this) && !elLastChild.animated) { // Insert to end of list + // If already at end of list: Do not insert if (elLastChild === dragEl) { return completed(false); - } // if there is a last element, it is the target - + } + // if there is a last element, it is the target if (elLastChild && el === evt.target) { target = elLastChild; } - if (target) { targetRect = getRect(target); } - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, !!target) !== false) { capture(); - el.appendChild(dragEl); + if (elLastChild && elLastChild.nextSibling) { + // the last draggable element is not the last node + el.insertBefore(dragEl, elLastChild.nextSibling); + } else { + el.appendChild(dragEl); + } parentEl = el; // actualization changed(); @@ -2042,14 +1804,11 @@ } else if (elLastChild && _ghostIsFirst(evt, vertical, this)) { // Insert to start of list var firstChild = getChild(el, 0, options, true); - if (firstChild === dragEl) { return completed(false); } - target = firstChild; targetRect = getRect(target); - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, false) !== false) { capture(); el.insertBefore(dragEl, firstChild); @@ -2061,82 +1820,68 @@ } else if (target.parentNode === el) { targetRect = getRect(target); var direction = 0, - targetBeforeFirstSwap, - differentLevel = dragEl.parentNode !== el, - differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), - side1 = vertical ? 'top' : 'left', - scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), - scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; - + targetBeforeFirstSwap, + differentLevel = dragEl.parentNode !== el, + differentRowCol = !_dragElInRowColumn(dragEl.animated && dragEl.toRect || dragRect, target.animated && target.toRect || targetRect, vertical), + side1 = vertical ? 'top' : 'left', + scrolledPastTop = isScrolledPast(target, 'top', 'top') || isScrolledPast(dragEl, 'top', 'top'), + scrollBefore = scrolledPastTop ? scrolledPastTop.scrollTop : void 0; if (lastTarget !== target) { targetBeforeFirstSwap = targetRect[side1]; pastFirstInvertThresh = false; isCircumstantialInvert = !differentRowCol && options.invertSwap || differentLevel; } - direction = _getSwapDirection(evt, target, targetRect, vertical, differentRowCol ? 1 : options.swapThreshold, options.invertedSwapThreshold == null ? options.swapThreshold : options.invertedSwapThreshold, isCircumstantialInvert, lastTarget === target); var sibling; - if (direction !== 0) { // Check if target is beside dragEl in respective direction (ignoring hidden elements) var dragIndex = index(dragEl); - do { dragIndex -= direction; sibling = parentEl.children[dragIndex]; } while (sibling && (css(sibling, 'display') === 'none' || sibling === ghostEl)); - } // If dragEl is already beside target: Do not insert - - + } + // If dragEl is already beside target: Do not insert if (direction === 0 || sibling === target) { return completed(false); } - lastTarget = target; lastDirection = direction; var nextSibling = target.nextElementSibling, - after = false; + after = false; after = direction === 1; - var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); - if (moveVector !== false) { if (moveVector === 1 || moveVector === -1) { after = moveVector === 1; } - _silent = true; setTimeout(_unsilent, 30); capture(); - if (after && !nextSibling) { el.appendChild(dragEl); } else { target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } // Undo chrome's scroll adjustment (has no effect on other browsers) - + } + // Undo chrome's scroll adjustment (has no effect on other browsers) if (scrolledPastTop) { scrollBy(scrolledPastTop, 0, scrollBefore - scrolledPastTop.scrollTop); } - parentEl = dragEl.parentNode; // actualization - // must be done before animation + // must be done before animation if (targetBeforeFirstSwap !== undefined && !isCircumstantialInvert) { targetMoveDistance = Math.abs(targetBeforeFirstSwap - getRect(target)[side1]); } - changed(); return completed(true); } } - if (el.contains(dragEl)) { return completed(false); } } - return false; }, _ignoreWhileAnimating: null, @@ -2156,83 +1901,69 @@ off(ownerDocument, 'touchcancel', this._onDrop); off(document, 'selectstart', this); }, - _onDrop: function _onDrop( - /**Event*/ - evt) { + _onDrop: function _onDrop( /**Event*/evt) { var el = this.el, - options = this.options; // Get the index of the dragged element within its parent + options = this.options; + // Get the index of the dragged element within its parent newIndex = index(dragEl); newDraggableIndex = index(dragEl, options.draggable); pluginEvent('drop', this, { evt: evt }); - parentEl = dragEl && dragEl.parentNode; // Get again after plugin event + parentEl = dragEl && dragEl.parentNode; + // Get again after plugin event newIndex = index(dragEl); newDraggableIndex = index(dragEl, options.draggable); - if (Sortable.eventCanceled) { this._nulling(); - return; } - awaitingDragStarted = false; isCircumstantialInvert = false; pastFirstInvertThresh = false; clearInterval(this._loopId); clearTimeout(this._dragStartTimer); - _cancelNextTick(this.cloneId); + _cancelNextTick(this._dragStartId); - _cancelNextTick(this._dragStartId); // Unbind events - - + // Unbind events if (this.nativeDraggable) { off(document, 'drop', this); off(el, 'dragstart', this._onDragStart); } - this._offMoveEvents(); - this._offUpEvents(); - if (Safari) { css(document.body, 'user-select', ''); } - css(dragEl, 'transform', ''); - if (evt) { if (moved) { evt.cancelable && evt.preventDefault(); !options.dropBubble && evt.stopPropagation(); } - ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { // Remove clone(s) cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); } - if (dragEl) { if (this.nativeDraggable) { off(dragEl, 'dragend', this); } - _disableDraggable(dragEl); + dragEl.style['will-change'] = ''; - dragEl.style['will-change'] = ''; // Remove classes + // Remove classes // ghostClass is added in dragStarted - if (moved && !awaitingDragStarted) { toggleClass(dragEl, putSortable ? putSortable.options.ghostClass : this.options.ghostClass, false); } + toggleClass(dragEl, this.options.chosenClass, false); - toggleClass(dragEl, this.options.chosenClass, false); // Drag stop event - + // Drag stop event _dispatchEvent({ sortable: this, name: 'unchoose', @@ -2241,7 +1972,6 @@ newDraggableIndex: null, originalEvent: evt }); - if (rootEl !== parentEl) { if (newIndex >= 0) { // Add event @@ -2251,17 +1981,17 @@ toEl: parentEl, fromEl: rootEl, originalEvent: evt - }); // Remove event - + }); + // Remove event _dispatchEvent({ sortable: this, name: 'remove', toEl: parentEl, originalEvent: evt - }); // drag from one list and drop into another - + }); + // drag from one list and drop into another _dispatchEvent({ rootEl: parentEl, name: 'sort', @@ -2269,7 +1999,6 @@ fromEl: rootEl, originalEvent: evt }); - _dispatchEvent({ sortable: this, name: 'sort', @@ -2277,7 +2006,6 @@ originalEvent: evt }); } - putSortable && putSortable.save(); } else { if (newIndex !== oldIndex) { @@ -2289,7 +2017,6 @@ toEl: parentEl, originalEvent: evt }); - _dispatchEvent({ sortable: this, name: 'sort', @@ -2299,27 +2026,24 @@ } } } - if (Sortable.active) { /* jshint eqnull:true */ if (newIndex == null || newIndex === -1) { newIndex = oldIndex; newDraggableIndex = oldDraggableIndex; } - _dispatchEvent({ sortable: this, name: 'end', toEl: parentEl, originalEvent: evt - }); // Save sorting - + }); + // Save sorting this.save(); } } } - this._nulling(); }, _nulling: function _nulling() { @@ -2330,65 +2054,52 @@ }); savedInputChecked.length = lastDx = lastDy = 0; }, - handleEvent: function handleEvent( - /**Event*/ - evt) { + handleEvent: function handleEvent( /**Event*/evt) { switch (evt.type) { case 'drop': case 'dragend': this._onDrop(evt); - break; - case 'dragenter': case 'dragover': if (dragEl) { this._onDragOver(evt); - _globalDragOver(evt); } - break; - case 'selectstart': evt.preventDefault(); break; } }, - /** * Serializes the item into an array of string. * @returns {String[]} */ toArray: function toArray() { var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; for (; i < n; i++) { el = children[i]; - if (closest(el, options.draggable, this.el, false)) { order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); } } - return order; }, - /** * Sorts the elements according to the array. * @param {String[]} order order of the items */ sort: function sort(order, useAnimation) { var items = {}, - rootEl = this.el; + rootEl = this.el; this.toArray().forEach(function (id, i) { var el = rootEl.children[i]; - if (closest(el, this.options.draggable, rootEl, false)) { items[id] = el; } @@ -2402,7 +2113,6 @@ }); useAnimation && this.animateAll(); }, - /** * Save the current sorting */ @@ -2410,7 +2120,6 @@ var store = this.options.store; store && store.set && store.set(this); }, - /** * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. * @param {HTMLElement} el @@ -2420,7 +2129,6 @@ closest: function closest$1(el, selector) { return closest(el, selector || this.options.draggable, this.el, false); }, - /** * Set/get option * @param {string} name @@ -2429,24 +2137,20 @@ */ option: function option(name, value) { var options = this.options; - if (value === void 0) { return options[name]; } else { var modifiedValue = PluginManager.modifyOption(this, name, value); - if (typeof modifiedValue !== 'undefined') { options[name] = modifiedValue; } else { options[name] = value; } - if (name === 'group') { _prepareGroup(options); } } }, - /** * Destroy */ @@ -2457,21 +2161,16 @@ off(el, 'mousedown', this._onTapStart); off(el, 'touchstart', this._onTapStart); off(el, 'pointerdown', this._onTapStart); - if (this.nativeDraggable) { off(el, 'dragover', this); off(el, 'dragenter', this); - } // Remove draggable attributes - - + } + // Remove draggable attributes Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { el.removeAttribute('draggable'); }); - this._onDrop(); - this._disableDelayedDragEvents(); - sortables.splice(sortables.indexOf(this.el), 1); this.el = el = null; }, @@ -2480,25 +2179,22 @@ pluginEvent('hideClone', this); if (Sortable.eventCanceled) return; css(cloneEl, 'display', 'none'); - if (this.options.removeCloneOnHide && cloneEl.parentNode) { cloneEl.parentNode.removeChild(cloneEl); } - cloneHidden = true; } }, _showClone: function _showClone(putSortable) { if (putSortable.lastPutMode !== 'clone') { this._hideClone(); - return; } - if (cloneHidden) { pluginEvent('showClone', this); - if (Sortable.eventCanceled) return; // show clone at dragEl or original position + if (Sortable.eventCanceled) return; + // show clone at dragEl or original position if (dragEl.parentNode == rootEl && !this.options.group.revertClone) { rootEl.insertBefore(cloneEl, dragEl); } else if (nextEl) { @@ -2506,33 +2202,26 @@ } else { rootEl.appendChild(cloneEl); } - if (this.options.group.revertClone) { this.animate(dragEl, cloneEl); } - css(cloneEl, 'display', ''); cloneHidden = false; } } }; - - function _globalDragOver( - /**Event*/ - evt) { + function _globalDragOver( /**Event*/evt) { if (evt.dataTransfer) { evt.dataTransfer.dropEffect = 'move'; } - evt.cancelable && evt.preventDefault(); } - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvent, willInsertAfter) { var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; // Support for new CustomEvent feature - + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; + // Support for new CustomEvent feature if (window.CustomEvent && !IE11OrLess && !Edge) { evt = new CustomEvent('move', { bubbles: true, @@ -2542,7 +2231,6 @@ evt = document.createEvent('Event'); evt.initEvent('move', true, true); } - evt.to = toEl; evt.from = fromEl; evt.dragged = dragEl; @@ -2552,41 +2240,35 @@ evt.willInsertAfter = willInsertAfter; evt.originalEvent = originalEvent; fromEl.dispatchEvent(evt); - if (onMoveFn) { retVal = onMoveFn.call(sortable, evt, originalEvent); } - return retVal; } - function _disableDraggable(el) { el.draggable = false; } - function _unsilent() { _silent = false; } - function _ghostIsFirst(evt, vertical, sortable) { - var rect = getRect(getChild(sortable.el, 0, sortable.options, true)); + var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true)); + var sortableContentRect = getContentRect(sortable.el); var spacer = 10; - return vertical ? evt.clientX < rect.left - spacer || evt.clientY < rect.top && evt.clientX < rect.right : evt.clientY < rect.top - spacer || evt.clientY < rect.bottom && evt.clientX < rect.left; + return vertical ? evt.clientX < sortableContentRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < sortableContentRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left; } - function _ghostIsLast(evt, vertical, sortable) { - var rect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable)); + var sortableContentRect = getContentRect(sortable.el); var spacer = 10; - return vertical ? evt.clientX > rect.right + spacer || evt.clientX <= rect.right && evt.clientY > rect.bottom && evt.clientX >= rect.left : evt.clientX > rect.right && evt.clientY > rect.top || evt.clientX <= rect.right && evt.clientY > rect.bottom + spacer; + return vertical ? evt.clientX > sortableContentRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > sortableContentRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top; } - function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { var mouseOnAxis = vertical ? evt.clientY : evt.clientX, - targetLength = vertical ? targetRect.height : targetRect.width, - targetS1 = vertical ? targetRect.top : targetRect.left, - targetS2 = vertical ? targetRect.bottom : targetRect.right, - invert = false; - + targetLength = vertical ? targetRect.height : targetRect.width, + targetS1 = vertical ? targetRect.top : targetRect.left, + targetS2 = vertical ? targetRect.bottom : targetRect.right, + invert = false; if (!invertSwap) { // Never invert or create dragEl shadow when target movemenet causes mouse to move past the end of regular swapThreshold if (isLastTarget && targetMoveDistance < targetLength * swapThreshold) { @@ -2596,7 +2278,6 @@ // past first invert threshold, do not restrict inverted threshold to dragEl shadow pastFirstInvertThresh = true; } - if (!pastFirstInvertThresh) { // dragEl shadow (target move distance shadow) if (lastDirection === 1 ? mouseOnAxis < targetS1 + targetMoveDistance // over dragEl shadow @@ -2613,26 +2294,22 @@ } } } - invert = invert || invertSwap; - if (invert) { // Invert of regular if (mouseOnAxis < targetS1 + targetLength * invertedSwapThreshold / 2 || mouseOnAxis > targetS2 - targetLength * invertedSwapThreshold / 2) { return mouseOnAxis > targetS1 + targetLength / 2 ? 1 : -1; } } - return 0; } + /** * Gets the direction dragEl must be swapped relative to target in order to make it * seem that dragEl has been "inserted" into that element's position * @param {HTMLElement} target The target whose position dragEl is being inserted at * @return {Number} Direction dragEl must be swapped */ - - function _getInsertDirection(target) { if (index(dragEl) < index(target)) { return 1; @@ -2640,55 +2317,48 @@ return -1; } } + /** * Generate id * @param {HTMLElement} el * @returns {String} * @private */ - - function _generateId(el) { var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - + i = str.length, + sum = 0; while (i--) { sum += str.charCodeAt(i); } - return sum.toString(36); } - function _saveInputCheckedState(root) { savedInputChecked.length = 0; var inputs = root.getElementsByTagName('input'); var idx = inputs.length; - while (idx--) { var el = inputs[idx]; el.checked && savedInputChecked.push(el); } } - function _nextTick(fn) { return setTimeout(fn, 0); } - function _cancelNextTick(id) { return clearTimeout(id); - } // Fixed #973: - + } + // Fixed #973: if (documentExists) { on(document, 'touchmove', function (evt) { if ((Sortable.active || awaitingDragStarted) && evt.cancelable) { evt.preventDefault(); } }); - } // Export utils - + } + // Export utils Sortable.utils = { on: on, off: off, @@ -2708,59 +2378,54 @@ detectDirection: _detectDirection, getChild: getChild }; + /** * Get the Sortable instance of an element * @param {HTMLElement} element The element * @return {Sortable|undefined} The instance of Sortable */ - Sortable.get = function (element) { return element[expando]; }; + /** * Mount a plugin to Sortable * @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted */ - - Sortable.mount = function () { for (var _len = arguments.length, plugins = new Array(_len), _key = 0; _key < _len; _key++) { plugins[_key] = arguments[_key]; } - if (plugins[0].constructor === Array) plugins = plugins[0]; plugins.forEach(function (plugin) { if (!plugin.prototype || !plugin.prototype.constructor) { throw "Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(plugin)); } - if (plugin.utils) Sortable.utils = _objectSpread2(_objectSpread2({}, Sortable.utils), plugin.utils); PluginManager.mount(plugin); }); }; + /** * Create sortable instance * @param {HTMLElement} el * @param {Object} [options] */ - - Sortable.create = function (el, options) { return new Sortable(el, options); - }; // Export - + }; + // Export Sortable.version = version; var autoScrolls = [], - scrollEl, - scrollRootEl, - scrolling = false, - lastAutoScrollX, - lastAutoScrollY, - touchEvt$1, - pointerElemChangedInterval; - + scrollEl, + scrollRootEl, + scrolling = false, + lastAutoScrollX, + lastAutoScrollY, + touchEvt$1, + pointerElemChangedInterval; function AutoScrollPlugin() { function AutoScroll() { this.defaults = { @@ -2769,19 +2434,18 @@ scrollSensitivity: 30, scrollSpeed: 10, bubbleScroll: true - }; // Bind all private methods + }; + // Bind all private methods for (var fn in this) { if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { this[fn] = this[fn].bind(this); } } } - AutoScroll.prototype = { dragStarted: function dragStarted(_ref) { var originalEvent = _ref.originalEvent; - if (this.sortable.nativeDraggable) { on(document, 'dragover', this._handleAutoScroll); } else { @@ -2796,7 +2460,6 @@ }, dragOverCompleted: function dragOverCompleted(_ref2) { var originalEvent = _ref2.originalEvent; - // For when bubbling is canceled and using fallback (fallback 'touchmove' always reached) if (!this.options.dragOverBubble && !originalEvent.rootEl) { this._handleAutoScroll(originalEvent); @@ -2810,7 +2473,6 @@ off(document, 'touchmove', this._handleFallbackAutoScroll); off(document, 'mousemove', this._handleFallbackAutoScroll); } - clearPointerElemChangedInterval(); clearAutoScrolls(); cancelThrottle(); @@ -2824,31 +2486,29 @@ }, _handleAutoScroll: function _handleAutoScroll(evt, fallback) { var _this = this; - var x = (evt.touches ? evt.touches[0] : evt).clientX, - y = (evt.touches ? evt.touches[0] : evt).clientY, - elem = document.elementFromPoint(x, y); - touchEvt$1 = evt; // IE does not seem to have native autoscroll, + y = (evt.touches ? evt.touches[0] : evt).clientY, + elem = document.elementFromPoint(x, y); + touchEvt$1 = evt; + + // IE does not seem to have native autoscroll, // Edge's autoscroll seems too conditional, // MACOS Safari does not have autoscroll, // Firefox and Chrome are good - if (fallback || this.options.forceAutoScrollFallback || Edge || IE11OrLess || Safari) { - autoScroll(evt, this.options, elem, fallback); // Listener for pointer element change + autoScroll(evt, this.options, elem, fallback); + // Listener for pointer element change var ogElemScroller = getParentAutoScrollElement(elem, true); - if (scrolling && (!pointerElemChangedInterval || x !== lastAutoScrollX || y !== lastAutoScrollY)) { - pointerElemChangedInterval && clearPointerElemChangedInterval(); // Detect for pointer elem change, emulating native DnD behaviour - + pointerElemChangedInterval && clearPointerElemChangedInterval(); + // Detect for pointer elem change, emulating native DnD behaviour pointerElemChangedInterval = setInterval(function () { var newElem = getParentAutoScrollElement(document.elementFromPoint(x, y), true); - if (newElem !== ogElemScroller) { ogElemScroller = newElem; clearAutoScrolls(); } - autoScroll(evt, _this.options, newElem, fallback); }, 10); lastAutoScrollX = x; @@ -2860,7 +2520,6 @@ clearAutoScrolls(); return; } - autoScroll(evt, this.options, getParentAutoScrollElement(elem, false), false); } } @@ -2870,60 +2529,54 @@ initializeByDefault: true }); } - function clearAutoScrolls() { autoScrolls.forEach(function (autoScroll) { clearInterval(autoScroll.pid); }); autoScrolls = []; } - function clearPointerElemChangedInterval() { clearInterval(pointerElemChangedInterval); } - var autoScroll = throttle(function (evt, options, rootEl, isFallback) { // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 if (!options.scroll) return; var x = (evt.touches ? evt.touches[0] : evt).clientX, - y = (evt.touches ? evt.touches[0] : evt).clientY, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - winScroller = getWindowScrollingElement(); + y = (evt.touches ? evt.touches[0] : evt).clientY, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + winScroller = getWindowScrollingElement(); var scrollThisInstance = false, - scrollCustomFn; // New scroll root, set scrollEl + scrollCustomFn; + // New scroll root, set scrollEl if (scrollRootEl !== rootEl) { scrollRootEl = rootEl; clearAutoScrolls(); scrollEl = options.scroll; scrollCustomFn = options.scrollFn; - if (scrollEl === true) { scrollEl = getParentAutoScrollElement(rootEl, true); } } - var layersOut = 0; var currentParent = scrollEl; - do { var el = currentParent, - rect = getRect(el), - top = rect.top, - bottom = rect.bottom, - left = rect.left, - right = rect.right, - width = rect.width, - height = rect.height, - canScrollX = void 0, - canScrollY = void 0, - scrollWidth = el.scrollWidth, - scrollHeight = el.scrollHeight, - elCSS = css(el), - scrollPosX = el.scrollLeft, - scrollPosY = el.scrollTop; - + rect = getRect(el), + top = rect.top, + bottom = rect.bottom, + left = rect.left, + right = rect.right, + width = rect.width, + height = rect.height, + canScrollX = void 0, + canScrollY = void 0, + scrollWidth = el.scrollWidth, + scrollHeight = el.scrollHeight, + elCSS = css(el), + scrollPosX = el.scrollLeft, + scrollPosY = el.scrollTop; if (el === winScroller) { canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll' || elCSS.overflowX === 'visible'); canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll' || elCSS.overflowY === 'visible'); @@ -2931,10 +2584,8 @@ canScrollX = width < scrollWidth && (elCSS.overflowX === 'auto' || elCSS.overflowX === 'scroll'); canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll'); } - var vx = canScrollX && (Math.abs(right - x) <= sens && scrollPosX + width < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX); var vy = canScrollY && (Math.abs(bottom - y) <= sens && scrollPosY + height < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY); - if (!autoScrolls[layersOut]) { for (var i = 0; i <= layersOut; i++) { if (!autoScrolls[i]) { @@ -2942,61 +2593,51 @@ } } } - if (autoScrolls[layersOut].vx != vx || autoScrolls[layersOut].vy != vy || autoScrolls[layersOut].el !== el) { autoScrolls[layersOut].el = el; autoScrolls[layersOut].vx = vx; autoScrolls[layersOut].vy = vy; clearInterval(autoScrolls[layersOut].pid); - if (vx != 0 || vy != 0) { scrollThisInstance = true; /* jshint loopfunc:true */ - autoScrolls[layersOut].pid = setInterval(function () { // emulate drag over during autoscroll (fallback), emulating native DnD behaviour if (isFallback && this.layer === 0) { Sortable.active._onTouchMove(touchEvt$1); // To move ghost if it is positioned absolutely - } - var scrollOffsetY = autoScrolls[this.layer].vy ? autoScrolls[this.layer].vy * speed : 0; var scrollOffsetX = autoScrolls[this.layer].vx ? autoScrolls[this.layer].vx * speed : 0; - if (typeof scrollCustomFn === 'function') { if (scrollCustomFn.call(Sortable.dragged.parentNode[expando], scrollOffsetX, scrollOffsetY, evt, touchEvt$1, autoScrolls[this.layer].el) !== 'continue') { return; } } - scrollBy(autoScrolls[this.layer].el, scrollOffsetX, scrollOffsetY); }.bind({ layer: layersOut }), 24); } } - layersOut++; } while (options.bubbleScroll && currentParent !== winScroller && (currentParent = getParentAutoScrollElement(currentParent, false))); - scrolling = scrollThisInstance; // in case another function catches scrolling as false in between when it is not }, 30); var drop = function drop(_ref) { var originalEvent = _ref.originalEvent, - putSortable = _ref.putSortable, - dragEl = _ref.dragEl, - activeSortable = _ref.activeSortable, - dispatchSortableEvent = _ref.dispatchSortableEvent, - hideGhostForTarget = _ref.hideGhostForTarget, - unhideGhostForTarget = _ref.unhideGhostForTarget; + putSortable = _ref.putSortable, + dragEl = _ref.dragEl, + activeSortable = _ref.activeSortable, + dispatchSortableEvent = _ref.dispatchSortableEvent, + hideGhostForTarget = _ref.hideGhostForTarget, + unhideGhostForTarget = _ref.unhideGhostForTarget; if (!originalEvent) return; var toSortable = putSortable || activeSortable; hideGhostForTarget(); var touch = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches[0] : originalEvent; var target = document.elementFromPoint(touch.clientX, touch.clientY); unhideGhostForTarget(); - if (toSortable && !toSortable.el.contains(target)) { dispatchSortableEvent('spill'); this.onSpill({ @@ -3005,9 +2646,7 @@ }); } }; - function Revert() {} - Revert.prototype = { startIndex: null, dragStart: function dragStart(_ref2) { @@ -3016,40 +2655,32 @@ }, onSpill: function onSpill(_ref3) { var dragEl = _ref3.dragEl, - putSortable = _ref3.putSortable; + putSortable = _ref3.putSortable; this.sortable.captureAnimationState(); - if (putSortable) { putSortable.captureAnimationState(); } - var nextSibling = getChild(this.sortable.el, this.startIndex, this.options); - if (nextSibling) { this.sortable.el.insertBefore(dragEl, nextSibling); } else { this.sortable.el.appendChild(dragEl); } - this.sortable.animateAll(); - if (putSortable) { putSortable.animateAll(); } }, drop: drop }; - _extends(Revert, { pluginName: 'revertOnSpill' }); - function Remove() {} - Remove.prototype = { onSpill: function onSpill(_ref4) { var dragEl = _ref4.dragEl, - putSortable = _ref4.putSortable; + putSortable = _ref4.putSortable; var parentSortable = putSortable || this.sortable; parentSortable.captureAnimationState(); dragEl.parentNode && dragEl.parentNode.removeChild(dragEl); @@ -3057,20 +2688,17 @@ }, drop: drop }; - _extends(Remove, { pluginName: 'removeOnSpill' }); var lastSwapEl; - function SwapPlugin() { function Swap() { this.defaults = { swapClass: 'sortable-swap-highlight' }; } - Swap.prototype = { dragStart: function dragStart(_ref) { var dragEl = _ref.dragEl; @@ -3078,42 +2706,37 @@ }, dragOverValid: function dragOverValid(_ref2) { var completed = _ref2.completed, - target = _ref2.target, - onMove = _ref2.onMove, - activeSortable = _ref2.activeSortable, - changed = _ref2.changed, - cancel = _ref2.cancel; + target = _ref2.target, + onMove = _ref2.onMove, + activeSortable = _ref2.activeSortable, + changed = _ref2.changed, + cancel = _ref2.cancel; if (!activeSortable.options.swap) return; var el = this.sortable.el, - options = this.options; - + options = this.options; if (target && target !== el) { var prevSwapEl = lastSwapEl; - if (onMove(target) !== false) { toggleClass(target, options.swapClass, true); lastSwapEl = target; } else { lastSwapEl = null; } - if (prevSwapEl && prevSwapEl !== lastSwapEl) { toggleClass(prevSwapEl, options.swapClass, false); } } - changed(); completed(true); cancel(); }, drop: function drop(_ref3) { var activeSortable = _ref3.activeSortable, - putSortable = _ref3.putSortable, - dragEl = _ref3.dragEl; + putSortable = _ref3.putSortable, + dragEl = _ref3.dragEl; var toSortable = putSortable || this.sortable; var options = this.options; lastSwapEl && toggleClass(lastSwapEl, options.swapClass, false); - if (lastSwapEl && (options.swap || putSortable && putSortable.options.swap)) { if (dragEl !== lastSwapEl) { toSortable.captureAnimationState(); @@ -3137,38 +2760,34 @@ } }); } - function swapNodes(n1, n2) { var p1 = n1.parentNode, - p2 = n2.parentNode, - i1, - i2; + p2 = n2.parentNode, + i1, + i2; if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return; i1 = index(n1); i2 = index(n2); - if (p1.isEqualNode(p2) && i1 < i2) { i2++; } - p1.insertBefore(n2, p1.children[i1]); p2.insertBefore(n1, p2.children[i2]); } var multiDragElements = [], - multiDragClones = [], - lastMultiDragSelect, - // for selection with modifier key down (SHIFT) - multiDragSortable, - initialFolding = false, - // Initial multi-drag fold when drag started - folding = false, - // Folding any other time - dragStarted = false, - dragEl$1, - clonesFromRect, - clonesHidden; - + multiDragClones = [], + lastMultiDragSelect, + // for selection with modifier key down (SHIFT) + multiDragSortable, + initialFolding = false, + // Initial multi-drag fold when drag started + folding = false, + // Folding any other time + dragStarted = false, + dragEl$1, + clonesFromRect, + clonesHidden; function MultiDragPlugin() { function MultiDrag(sortable) { // Bind all private methods @@ -3177,22 +2796,22 @@ this[fn] = this[fn].bind(this); } } - - if (sortable.options.supportPointer) { - on(document, 'pointerup', this._deselectMultiDrag); - } else { - on(document, 'mouseup', this._deselectMultiDrag); - on(document, 'touchend', this._deselectMultiDrag); + if (!sortable.options.avoidImplicitDeselect) { + if (sortable.options.supportPointer) { + on(document, 'pointerup', this._deselectMultiDrag); + } else { + on(document, 'mouseup', this._deselectMultiDrag); + on(document, 'touchend', this._deselectMultiDrag); + } } - on(document, 'keydown', this._checkKeyDown); on(document, 'keyup', this._checkKeyUp); this.defaults = { selectedClass: 'sortable-selected', multiDragKey: null, + avoidImplicitDeselect: false, setData: function setData(dataTransfer, dragEl) { var data = ''; - if (multiDragElements.length && multiDragSortable === sortable) { multiDragElements.forEach(function (multiDragElement, i) { data += (!i ? '' : ', ') + multiDragElement.textContent; @@ -3200,12 +2819,10 @@ } else { data = dragEl.textContent; } - dataTransfer.setData('Text', data); } }; } - MultiDrag.prototype = { multiDragKeyDown: false, isMultiDrag: false, @@ -3218,9 +2835,8 @@ }, setupClone: function setupClone(_ref2) { var sortable = _ref2.sortable, - cancel = _ref2.cancel; + cancel = _ref2.cancel; if (!this.isMultiDrag) return; - for (var i = 0; i < multiDragElements.length; i++) { multiDragClones.push(clone(multiDragElements[i])); multiDragClones[i].sortableIndex = multiDragElements[i].sortableIndex; @@ -3229,18 +2845,15 @@ toggleClass(multiDragClones[i], this.options.selectedClass, false); multiDragElements[i] === dragEl$1 && toggleClass(multiDragClones[i], this.options.chosenClass, false); } - sortable._hideClone(); - cancel(); }, clone: function clone(_ref3) { var sortable = _ref3.sortable, - rootEl = _ref3.rootEl, - dispatchSortableEvent = _ref3.dispatchSortableEvent, - cancel = _ref3.cancel; + rootEl = _ref3.rootEl, + dispatchSortableEvent = _ref3.dispatchSortableEvent, + cancel = _ref3.cancel; if (!this.isMultiDrag) return; - if (!this.options.removeCloneOnHide) { if (multiDragElements.length && multiDragSortable === sortable) { insertMultiDragClones(true, rootEl); @@ -3251,8 +2864,8 @@ }, showClone: function showClone(_ref4) { var cloneNowShown = _ref4.cloneNowShown, - rootEl = _ref4.rootEl, - cancel = _ref4.cancel; + rootEl = _ref4.rootEl, + cancel = _ref4.cancel; if (!this.isMultiDrag) return; insertMultiDragClones(false, rootEl); multiDragClones.forEach(function (clone) { @@ -3264,14 +2877,12 @@ }, hideClone: function hideClone(_ref5) { var _this = this; - var sortable = _ref5.sortable, - cloneNowHidden = _ref5.cloneNowHidden, - cancel = _ref5.cancel; + cloneNowHidden = _ref5.cloneNowHidden, + cancel = _ref5.cancel; if (!this.isMultiDrag) return; multiDragClones.forEach(function (clone) { css(clone, 'display', 'none'); - if (_this.options.removeCloneOnHide && clone.parentNode) { clone.parentNode.removeChild(clone); } @@ -3282,15 +2893,14 @@ }, dragStartGlobal: function dragStartGlobal(_ref6) { var sortable = _ref6.sortable; - if (!this.isMultiDrag && multiDragSortable) { multiDragSortable.multiDrag._deselectMultiDrag(); } - multiDragElements.forEach(function (multiDragElement) { multiDragElement.sortableIndex = index(multiDragElement); - }); // Sort multi-drag elements + }); + // Sort multi-drag elements multiDragElements = multiDragElements.sort(function (a, b) { return a.sortableIndex - b.sortableIndex; }); @@ -3298,10 +2908,8 @@ }, dragStarted: function dragStarted(_ref7) { var _this2 = this; - var sortable = _ref7.sortable; if (!this.isMultiDrag) return; - if (this.options.sort) { // Capture rects, // hide multi drag elements (by positioning them absolute), @@ -3309,8 +2917,8 @@ // show multi drag elements, // animate to rects, // unset rects & remove from DOM - sortable.captureAnimationState(); + sortable.captureAnimationState(); if (this.options.animation) { multiDragElements.forEach(function (multiDragElement) { if (multiDragElement === dragEl$1) return; @@ -3325,18 +2933,16 @@ initialFolding = true; } } - sortable.animateAll(function () { folding = false; initialFolding = false; - if (_this2.options.animation) { multiDragElements.forEach(function (multiDragElement) { unsetRect(multiDragElement); }); - } // Remove all auxiliary multidrag items from el, if sorting enabled - + } + // Remove all auxiliary multidrag items from el, if sorting enabled if (_this2.options.sort) { removeMultiDragElements(); } @@ -3344,9 +2950,8 @@ }, dragOver: function dragOver(_ref8) { var target = _ref8.target, - completed = _ref8.completed, - cancel = _ref8.cancel; - + completed = _ref8.completed, + cancel = _ref8.cancel; if (folding && ~multiDragElements.indexOf(target)) { completed(false); cancel(); @@ -3354,10 +2959,9 @@ }, revert: function revert(_ref9) { var fromSortable = _ref9.fromSortable, - rootEl = _ref9.rootEl, - sortable = _ref9.sortable, - dragRect = _ref9.dragRect; - + rootEl = _ref9.rootEl, + sortable = _ref9.sortable, + dragRect = _ref9.dragRect; if (multiDragElements.length > 1) { // Setup unfold animation multiDragElements.forEach(function (multiDragElement) { @@ -3375,47 +2979,44 @@ }, dragOverCompleted: function dragOverCompleted(_ref10) { var sortable = _ref10.sortable, - isOwner = _ref10.isOwner, - insertion = _ref10.insertion, - activeSortable = _ref10.activeSortable, - parentEl = _ref10.parentEl, - putSortable = _ref10.putSortable; + isOwner = _ref10.isOwner, + insertion = _ref10.insertion, + activeSortable = _ref10.activeSortable, + parentEl = _ref10.parentEl, + putSortable = _ref10.putSortable; var options = this.options; - if (insertion) { // Clones must be hidden before folding animation to capture dragRectAbsolute properly if (isOwner) { activeSortable._hideClone(); } - - initialFolding = false; // If leaving sort:false root, or already folding - Fold to new location - + initialFolding = false; + // If leaving sort:false root, or already folding - Fold to new location if (options.animation && multiDragElements.length > 1 && (folding || !isOwner && !activeSortable.options.sort && !putSortable)) { // Fold: Set all multi drag elements's rects to dragEl's rect when multi-drag elements are invisible var dragRectAbsolute = getRect(dragEl$1, false, true, true); multiDragElements.forEach(function (multiDragElement) { if (multiDragElement === dragEl$1) return; - setRect(multiDragElement, dragRectAbsolute); // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted - // while folding, and so that we can capture them again because old sortable will no longer be fromSortable + setRect(multiDragElement, dragRectAbsolute); + // Move element(s) to end of parentEl so that it does not interfere with multi-drag clones insertion if they are inserted + // while folding, and so that we can capture them again because old sortable will no longer be fromSortable parentEl.appendChild(multiDragElement); }); folding = true; - } // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out - + } + // Clones must be shown (and check to remove multi drags) after folding when interfering multiDragElements are moved out if (!isOwner) { // Only remove if not folding (folding will remove them anyways) if (!folding) { removeMultiDragElements(); } - if (multiDragElements.length > 1) { var clonesHiddenBefore = clonesHidden; + activeSortable._showClone(sortable); - activeSortable._showClone(sortable); // Unfold animation for clones if showing from hidden - - + // Unfold animation for clones if showing from hidden if (activeSortable.options.animation && !clonesHidden && clonesHiddenBefore) { multiDragClones.forEach(function (clone) { activeSortable.addAnimationState({ @@ -3434,12 +3035,11 @@ }, dragOverAnimationCapture: function dragOverAnimationCapture(_ref11) { var dragRect = _ref11.dragRect, - isOwner = _ref11.isOwner, - activeSortable = _ref11.activeSortable; + isOwner = _ref11.isOwner, + activeSortable = _ref11.activeSortable; multiDragElements.forEach(function (multiDragElement) { multiDragElement.thisAnimationDuration = null; }); - if (activeSortable.options.animation && !isOwner && activeSortable.multiDrag.isMultiDrag) { clonesFromRect = _extends({}, dragRect); var dragMatrix = matrix(dragEl$1, true); @@ -3455,24 +3055,23 @@ }, drop: function drop(_ref12) { var evt = _ref12.originalEvent, - rootEl = _ref12.rootEl, - parentEl = _ref12.parentEl, - sortable = _ref12.sortable, - dispatchSortableEvent = _ref12.dispatchSortableEvent, - oldIndex = _ref12.oldIndex, - putSortable = _ref12.putSortable; + rootEl = _ref12.rootEl, + parentEl = _ref12.parentEl, + sortable = _ref12.sortable, + dispatchSortableEvent = _ref12.dispatchSortableEvent, + oldIndex = _ref12.oldIndex, + putSortable = _ref12.putSortable; var toSortable = putSortable || this.sortable; if (!evt) return; var options = this.options, - children = parentEl.children; // Multi-drag selection + children = parentEl.children; + // Multi-drag selection if (!dragStarted) { if (options.multiDragKey && !this.multiDragKeyDown) { this._deselectMultiDrag(); } - toggleClass(dragEl$1, options.selectedClass, !~multiDragElements.indexOf(dragEl$1)); - if (!~multiDragElements.indexOf(dragEl$1)) { multiDragElements.push(dragEl$1); dispatchEvent({ @@ -3480,18 +3079,17 @@ rootEl: rootEl, name: 'select', targetEl: dragEl$1, - originalEvt: evt - }); // Modifier activated, select from last to dragEl + originalEvent: evt + }); + // Modifier activated, select from last to dragEl if (evt.shiftKey && lastMultiDragSelect && sortable.el.contains(lastMultiDragSelect)) { var lastIndex = index(lastMultiDragSelect), - currentIndex = index(dragEl$1); - + currentIndex = index(dragEl$1); if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { // Must include lastMultiDragSelect (select it), in case modified selection from no selection // (but previous selection existed) var n, i; - if (currentIndex > lastIndex) { i = lastIndex; n = currentIndex; @@ -3499,7 +3097,6 @@ i = currentIndex; n = lastIndex + 1; } - for (; i < n; i++) { if (~multiDragElements.indexOf(children[i])) continue; toggleClass(children[i], options.selectedClass, true); @@ -3509,14 +3106,13 @@ rootEl: rootEl, name: 'select', targetEl: children[i], - originalEvt: evt + originalEvent: evt }); } } } else { lastMultiDragSelect = dragEl$1; } - multiDragSortable = toSortable; } else { multiDragElements.splice(multiDragElements.indexOf(dragEl$1), 1); @@ -3526,41 +3122,40 @@ rootEl: rootEl, name: 'deselect', targetEl: dragEl$1, - originalEvt: evt + originalEvent: evt }); } - } // Multi-drag drop - + } + // Multi-drag drop if (dragStarted && this.isMultiDrag) { - folding = false; // Do not "unfold" after around dragEl if reverted - + folding = false; + // Do not "unfold" after around dragEl if reverted if ((parentEl[expando].options.sort || parentEl !== rootEl) && multiDragElements.length > 1) { var dragRect = getRect(dragEl$1), - multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); + multiDragIndex = index(dragEl$1, ':not(.' + this.options.selectedClass + ')'); if (!initialFolding && options.animation) dragEl$1.thisAnimationDuration = null; toSortable.captureAnimationState(); - if (!initialFolding) { if (options.animation) { dragEl$1.fromRect = dragRect; multiDragElements.forEach(function (multiDragElement) { multiDragElement.thisAnimationDuration = null; - if (multiDragElement !== dragEl$1) { var rect = folding ? getRect(multiDragElement) : dragRect; - multiDragElement.fromRect = rect; // Prepare unfold animation + multiDragElement.fromRect = rect; + // Prepare unfold animation toSortable.addAnimationState({ target: multiDragElement, rect: rect }); } }); - } // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert - // properly they must all be removed - + } + // Multi drag elements are not necessarily removed from the DOM on drop, so to reinsert + // properly they must all be removed removeMultiDragElements(); multiDragElements.forEach(function (multiDragElement) { if (children[multiDragIndex]) { @@ -3568,12 +3163,12 @@ } else { parentEl.appendChild(multiDragElement); } - multiDragIndex++; - }); // If initial folding is done, the elements may have changed position because they are now + }); + + // If initial folding is done, the elements may have changed position because they are now // unfolding around dragEl, even though dragEl may not have his index changed, so update event // must be fired here as Sortable will not. - if (oldIndex === index(dragEl$1)) { var update = false; multiDragElements.forEach(function (multiDragElement) { @@ -3582,24 +3177,23 @@ return; } }); - if (update) { dispatchSortableEvent('update'); + dispatchSortableEvent('sort'); } } - } // Must be done after capturing individual rects (scroll bar) - + } + // Must be done after capturing individual rects (scroll bar) multiDragElements.forEach(function (multiDragElement) { unsetRect(multiDragElement); }); toSortable.animateAll(); } - multiDragSortable = toSortable; - } // Remove clones if necessary - + } + // Remove clones if necessary if (rootEl === parentEl || putSortable && putSortable.lastPutMode !== 'clone') { multiDragClones.forEach(function (clone) { clone.parentNode && clone.parentNode.removeChild(clone); @@ -3612,7 +3206,6 @@ }, destroyGlobal: function destroyGlobal() { this._deselectMultiDrag(); - off(document, 'pointerup', this._deselectMultiDrag); off(document, 'mouseup', this._deselectMultiDrag); off(document, 'touchend', this._deselectMultiDrag); @@ -3620,14 +3213,16 @@ off(document, 'keyup', this._checkKeyUp); }, _deselectMultiDrag: function _deselectMultiDrag(evt) { - if (typeof dragStarted !== "undefined" && dragStarted) return; // Only deselect if selection is in this sortable + if (typeof dragStarted !== "undefined" && dragStarted) return; - if (multiDragSortable !== this.sortable) return; // Only deselect if target is not item in this sortable + // Only deselect if selection is in this sortable + if (multiDragSortable !== this.sortable) return; - if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; // Only deselect if left click + // Only deselect if target is not item in this sortable + if (evt && closest(evt.target, this.options.draggable, this.sortable.el, false)) return; + // Only deselect if left click if (evt && evt.button !== 0) return; - while (multiDragElements.length) { var el = multiDragElements[0]; toggleClass(el, this.options.selectedClass, false); @@ -3637,7 +3232,7 @@ rootEl: this.sortable.el, name: 'deselect', targetEl: el, - originalEvt: evt + originalEvent: evt }); } }, @@ -3663,24 +3258,20 @@ select: function select(el) { var sortable = el.parentNode[expando]; if (!sortable || !sortable.options.multiDrag || ~multiDragElements.indexOf(el)) return; - if (multiDragSortable && multiDragSortable !== sortable) { multiDragSortable.multiDrag._deselectMultiDrag(); - multiDragSortable = sortable; } - toggleClass(el, sortable.options.selectedClass, true); multiDragElements.push(el); }, - /** * Deselects the provided multi-drag item * @param {HTMLElement} el The element to be deselected */ deselect: function deselect(el) { var sortable = el.parentNode[expando], - index = multiDragElements.indexOf(el); + index = multiDragElements.indexOf(el); if (!sortable || !sortable.options.multiDrag || !~index) return; toggleClass(el, sortable.options.selectedClass, false); multiDragElements.splice(index, 1); @@ -3688,17 +3279,16 @@ }, eventProperties: function eventProperties() { var _this3 = this; - var oldIndicies = [], - newIndicies = []; + newIndicies = []; multiDragElements.forEach(function (multiDragElement) { oldIndicies.push({ multiDragElement: multiDragElement, index: multiDragElement.sortableIndex - }); // multiDragElements will already be sorted if folding + }); + // multiDragElements will already be sorted if folding var newIndex; - if (folding && multiDragElement !== dragEl$1) { newIndex = -1; } else if (folding) { @@ -3706,7 +3296,6 @@ } else { newIndex = index(multiDragElement); } - newIndicies.push({ multiDragElement: multiDragElement, index: newIndex @@ -3722,23 +3311,19 @@ optionListeners: { multiDragKey: function multiDragKey(key) { key = key.toLowerCase(); - if (key === 'ctrl') { key = 'Control'; } else if (key.length > 1) { key = key.charAt(0).toUpperCase() + key.substr(1); } - return key; } } }); } - function insertMultiDragElements(clonesInserted, rootEl) { multiDragElements.forEach(function (multiDragElement, i) { var target = rootEl.children[multiDragElement.sortableIndex + (clonesInserted ? Number(i) : 0)]; - if (target) { rootEl.insertBefore(multiDragElement, target); } else { @@ -3746,17 +3331,15 @@ } }); } + /** * Insert multi-drag clones * @param {[Boolean]} elementsInserted Whether the multi-drag elements are inserted * @param {HTMLElement} rootEl */ - - function insertMultiDragClones(elementsInserted, rootEl) { multiDragClones.forEach(function (clone, i) { var target = rootEl.children[clone.sortableIndex + (elementsInserted ? Number(i) : 0)]; - if (target) { rootEl.insertBefore(clone, target); } else { @@ -3764,7 +3347,6 @@ } }); } - function removeMultiDragElements() { multiDragElements.forEach(function (multiDragElement) { if (multiDragElement === dragEl$1) return; diff --git a/Sortable.min.js b/Sortable.min.js index 7ba6b5903..1a9f19982 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.14.0 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function A(o){for(var t=1;tt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function N(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function I(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function P(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=P(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[j]._onDragOver(o)}}var i,r,a}function Yt(t){q&&q.parentNode[j]._isOutsideThisEl(t.target)}function Bt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[j]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return It(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Bt.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in K.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Pt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&At,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Et.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function Ft(t,e,n,o,i,r,a,l){var s,c,u=t[j],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||k(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function jt(t){t.draggable=!1}function Ht(){Ct=!1}function Lt(t){return setTimeout(t,0)}function Kt(t){return clearTimeout(t)}Bt.prototype={constructor:Bt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(gt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,q):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Tt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Tt.push(o)}}(o),!q&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=N(l,t.draggable,o,!1))&&l.animated||J===l)){if(nt=B(l),it=B(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return U({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),z("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=N(s,t.trim(),o,!1))return U({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),z("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!N(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!q&&n.parentNode===r&&(o=k(n),$=r,V=(q=n).parentNode,Q=q.nextSibling,J=n,at=a.group,st={target:Bt.dragged=q,clientX:(e||t).clientX,clientY:(e||t).clientY},ht=st.clientX-o.left,ft=st.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,q.style["will-change"]="all",o=function(){z("delayEnded",i,{evt:t}),Bt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(q.draggable=!0),i._triggerDragStart(t,e),U({sortable:i,name:"choose",originalEvent:t}),I(q,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(q,t.trim(),jt)}),h(l,"dragover",Xt),h(l,"mousemove",Xt),h(l,"touchmove",Xt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,q.draggable=!0),z("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Bt.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){q&&jt(q),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(q,"dragend",this),h($,"dragstart",this._onDragStart));try{document.selection?Lt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;yt=!1,$&&q?(z("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Yt),n=this.options,t||I(q,n.dragClass,!1),I(q,n.ghostClass,!0),Bt.active=this,t&&this._appendGhost(),U({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ct){this._lastX=ct.clientX,this._lastY=ct.clientY,kt();for(var t=document.elementFromPoint(ct.clientX,ct.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ct.clientX,ct.clientY))!==e;)e=t;if(q.parentNode[j]._isOutsideThisEl(t),e)do{if(e[j])if(e[j]._onDragOver({clientX:ct.clientX,clientY:ct.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Rt()}},_onTouchMove:function(t){if(st){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=Z&&v(Z,!0),a=Z&&r&&r.a,l=Z&&r&&r.d,e=Ot&&bt&&E(bt),a=(i.clientX-st.clientX+o.x)/(a||1)+(e?e[0]-_t[0]:0)/(a||1),l=(i.clientY-st.clientY+o.y)/(l||1)+(e?e[1]-_t[1]:0)/(l||1);if(!Bt.active&&!yt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))n.right+10||t.clientX<=n.right&&t.clientY>n.bottom&&t.clientX>=n.left:t.clientX>n.right&&t.clientY>n.top||t.clientX<=n.right&&t.clientY>n.bottom+10}(n,r,this)&&!g.animated){if(g===q)return O(!1);if((l=g&&a===n.target?g:l)&&(w=k(l)),!1!==Ft($,a,q,o,l,w,n,!!l))return x(),a.appendChild(q),V=a,M(),O(!0)}else if(g&&function(t,e,n){n=k(X(n.el,0,n.options,!0));return e?t.clientXt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&f(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[W]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[W]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[W]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in K.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&It,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[W],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Wt(t){return setTimeout(t,0)}function Kt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=H(l),rt=H(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},pt=ct.clientX-o.left,ft=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Wt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[W]._isOutsideThisEl(t),e)do{if(e[W])if(e[W]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=At&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(F((_=this).el,0,_.options,!0)),_=Y(_.el),e?t.clientX<_.left-10||t.clientY Date: Thu, 30 Nov 2023 22:29:44 +0000 Subject: [PATCH 39/41] Fix forkme ribbon --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 103cdfa6e..87162e8b3 100644 --- a/index.html +++ b/index.html @@ -17,7 +17,7 @@ - Fork me on GitHub + Fork me on GitHub
    From 73780bb2cb9fbc5c8d3a817fed66a593d152513f Mon Sep 17 00:00:00 2001 From: Owen Mills Date: Sun, 14 Jan 2024 10:43:00 +0000 Subject: [PATCH 40/41] 1.15.2 --- Sortable.js | 49 +++++++++++++++++++++++-------------------------- Sortable.min.js | 4 ++-- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Sortable.js b/Sortable.js index 242106c14..bb4ddcbe0 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,5 +1,5 @@ /**! - * Sortable 1.15.1 + * Sortable 1.15.2 * @author RubaXa * @author owenm * @license MIT @@ -134,7 +134,7 @@ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - var version = "1.15.1"; + var version = "1.15.2"; function userAgent(pattern) { if (typeof window !== 'undefined' && window.navigator) { @@ -335,26 +335,6 @@ }; } - /** - * Returns the content rect of the element (bounding rect minus border and padding) - * @param {HTMLElement} el - */ - function getContentRect(el) { - var rect = getRect(el); - var paddingLeft = parseInt(css(el, 'padding-left')), - paddingTop = parseInt(css(el, 'padding-top')), - paddingRight = parseInt(css(el, 'padding-right')), - paddingBottom = parseInt(css(el, 'padding-bottom')); - rect.top += paddingTop + parseInt(css(el, 'border-top-width')); - rect.left += paddingLeft + parseInt(css(el, 'border-left-width')); - // Client Width/Height includes padding only - rect.width = el.clientWidth - paddingLeft - paddingRight; - rect.height = el.clientHeight - paddingTop - paddingBottom; - rect.bottom = rect.top + rect.height; - rect.right = rect.left + rect.width; - return rect; - } - /** * Checks if a side of an element is scrolled past a side of its parents * @param {HTMLElement} el The element who's side being scrolled out of view is in question @@ -561,6 +541,23 @@ css(el, 'width', ''); css(el, 'height', ''); } + function getChildContainingRectFromElement(container, options, ghostEl) { + var rect = {}; + Array.from(container.children).forEach(function (child) { + var _rect$left, _rect$top, _rect$right, _rect$bottom; + if (!closest(child, options.draggable, container, false) || child.animated || child === ghostEl) return; + var childRect = getRect(child); + rect.left = Math.min((_rect$left = rect.left) !== null && _rect$left !== void 0 ? _rect$left : Infinity, childRect.left); + rect.top = Math.min((_rect$top = rect.top) !== null && _rect$top !== void 0 ? _rect$top : Infinity, childRect.top); + rect.right = Math.max((_rect$right = rect.right) !== null && _rect$right !== void 0 ? _rect$right : -Infinity, childRect.right); + rect.bottom = Math.max((_rect$bottom = rect.bottom) !== null && _rect$bottom !== void 0 ? _rect$bottom : -Infinity, childRect.bottom); + }); + rect.width = rect.right - rect.left; + rect.height = rect.bottom - rect.top; + rect.x = rect.left; + rect.y = rect.top; + return rect; + } var expando = 'Sortable' + new Date().getTime(); function AnimationStateManager() { @@ -2253,15 +2250,15 @@ } function _ghostIsFirst(evt, vertical, sortable) { var firstElRect = getRect(getChild(sortable.el, 0, sortable.options, true)); - var sortableContentRect = getContentRect(sortable.el); + var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl); var spacer = 10; - return vertical ? evt.clientX < sortableContentRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < sortableContentRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left; + return vertical ? evt.clientX < childContainingRect.left - spacer || evt.clientY < firstElRect.top && evt.clientX < firstElRect.right : evt.clientY < childContainingRect.top - spacer || evt.clientY < firstElRect.bottom && evt.clientX < firstElRect.left; } function _ghostIsLast(evt, vertical, sortable) { var lastElRect = getRect(lastChild(sortable.el, sortable.options.draggable)); - var sortableContentRect = getContentRect(sortable.el); + var childContainingRect = getChildContainingRectFromElement(sortable.el, sortable.options, ghostEl); var spacer = 10; - return vertical ? evt.clientX > sortableContentRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > sortableContentRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top; + return vertical ? evt.clientX > childContainingRect.right + spacer || evt.clientY > lastElRect.bottom && evt.clientX > lastElRect.left : evt.clientY > childContainingRect.bottom + spacer || evt.clientX > lastElRect.right && evt.clientY > lastElRect.top; } function _getSwapDirection(evt, target, targetRect, vertical, swapThreshold, invertedSwapThreshold, invertSwap, isLastTarget) { var mouseOnAxis = vertical ? evt.clientY : evt.clientX, diff --git a/Sortable.min.js b/Sortable.min.js index 1a9f19982..bb9953355 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.15.1 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function N(o){for(var t=1;tt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&f(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[W]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[W]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[W]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in K.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&It,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[W],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Wt(t){return setTimeout(t,0)}function Kt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=H(l),rt=H(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},pt=ct.clientX-o.left,ft=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Wt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[W]._isOutsideThisEl(t),e)do{if(e[W])if(e[W]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=At&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(F((_=this).el,0,_.options,!0)),_=Y(_.el),e?t.clientX<_.left-10||t.clientYt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientY Date: Thu, 28 Nov 2024 18:28:52 +0000 Subject: [PATCH 41/41] 1.15.6 --- Sortable.js | 98 +++++++++++++++++++++++++++++++------------------ Sortable.min.js | 4 +- 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/Sortable.js b/Sortable.js index bb4ddcbe0..07ecc1832 100644 --- a/Sortable.js +++ b/Sortable.js @@ -1,5 +1,5 @@ /**! - * Sortable 1.15.2 + * Sortable 1.15.6 * @author RubaXa * @author owenm * @license MIT @@ -134,7 +134,7 @@ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } - var version = "1.15.2"; + var version = "1.15.6"; function userAgent(pattern) { if (typeof window !== 'undefined' && window.navigator) { @@ -1127,7 +1127,8 @@ x: 0, y: 0 }, - supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && !Safari, + // Disabled on Safari: #1571; Enabled on Safari IOS: #2244 + supportPointer: Sortable.supportPointer !== false && 'PointerEvent' in window && (!Safari || IOS), emptyInsertThreshold: 5 }; PluginManager.initializePlugins(this, el, defaults); @@ -1238,7 +1239,7 @@ pluginEvent('filter', _this, { evt: evt }); - preventOnFilter && evt.cancelable && evt.preventDefault(); + preventOnFilter && evt.preventDefault(); return; // cancel dnd } } else if (filter) { @@ -1260,7 +1261,7 @@ } }); if (filter) { - preventOnFilter && evt.cancelable && evt.preventDefault(); + preventOnFilter && evt.preventDefault(); return; // cancel dnd } } @@ -1332,9 +1333,15 @@ on(ownerDocument, 'dragover', nearestEmptyInsertDetectEvent); on(ownerDocument, 'mousemove', nearestEmptyInsertDetectEvent); on(ownerDocument, 'touchmove', nearestEmptyInsertDetectEvent); - on(ownerDocument, 'mouseup', _this._onDrop); - on(ownerDocument, 'touchend', _this._onDrop); - on(ownerDocument, 'touchcancel', _this._onDrop); + if (options.supportPointer) { + on(ownerDocument, 'pointerup', _this._onDrop); + // Native D&D triggers pointercancel + !this.nativeDraggable && on(ownerDocument, 'pointercancel', _this._onDrop); + } else { + on(ownerDocument, 'mouseup', _this._onDrop); + on(ownerDocument, 'touchend', _this._onDrop); + on(ownerDocument, 'touchcancel', _this._onDrop); + } // Make dragEl draggable (must be before delay for FireFox) if (FireFox && this.nativeDraggable) { @@ -1354,9 +1361,14 @@ // If the user moves the pointer or let go the click or touch // before the delay has been reached: // disable the delayed drag - on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - on(ownerDocument, 'touchend', _this._disableDelayedDrag); - on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + if (options.supportPointer) { + on(ownerDocument, 'pointerup', _this._disableDelayedDrag); + on(ownerDocument, 'pointercancel', _this._disableDelayedDrag); + } else { + on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + on(ownerDocument, 'touchend', _this._disableDelayedDrag); + on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + } on(ownerDocument, 'mousemove', _this._delayedDragTouchMoveHandler); on(ownerDocument, 'touchmove', _this._delayedDragTouchMoveHandler); options.supportPointer && on(ownerDocument, 'pointermove', _this._delayedDragTouchMoveHandler); @@ -1382,6 +1394,8 @@ off(ownerDocument, 'mouseup', this._disableDelayedDrag); off(ownerDocument, 'touchend', this._disableDelayedDrag); off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + off(ownerDocument, 'pointerup', this._disableDelayedDrag); + off(ownerDocument, 'pointercancel', this._disableDelayedDrag); off(ownerDocument, 'mousemove', this._delayedDragTouchMoveHandler); off(ownerDocument, 'touchmove', this._delayedDragTouchMoveHandler); off(ownerDocument, 'pointermove', this._delayedDragTouchMoveHandler); @@ -1402,7 +1416,6 @@ } try { if (document.selection) { - // Timeout neccessary for IE9 _nextTick(function () { document.selection.empty(); }); @@ -1467,7 +1480,7 @@ } target = parent; // store last element } - /* jshint boss:true */ while (parent = parent.parentNode); + /* jshint boss:true */ while (parent = getParentOrHost(parent)); } _unhideGhostForTarget(); } @@ -1624,6 +1637,7 @@ _this._dragStartId = _nextTick(_this._dragStarted.bind(_this, fallback, evt)); on(document, 'selectstart', _this); moved = true; + window.getSelection().removeAllRanges(); if (Safari) { css(document.body, 'user-select', 'none'); } @@ -1895,6 +1909,7 @@ off(ownerDocument, 'mouseup', this._onDrop); off(ownerDocument, 'touchend', this._onDrop); off(ownerDocument, 'pointerup', this._onDrop); + off(ownerDocument, 'pointercancel', this._onDrop); off(ownerDocument, 'touchcancel', this._onDrop); off(document, 'selectstart', this); }, @@ -2373,7 +2388,8 @@ nextTick: _nextTick, cancelNextTick: _cancelNextTick, detectDirection: _detectDirection, - getChild: getChild + getChild: getChild, + expando: expando }; /** @@ -3084,28 +3100,38 @@ var lastIndex = index(lastMultiDragSelect), currentIndex = index(dragEl$1); if (~lastIndex && ~currentIndex && lastIndex !== currentIndex) { - // Must include lastMultiDragSelect (select it), in case modified selection from no selection - // (but previous selection existed) - var n, i; - if (currentIndex > lastIndex) { - i = lastIndex; - n = currentIndex; - } else { - i = currentIndex; - n = lastIndex + 1; - } - for (; i < n; i++) { - if (~multiDragElements.indexOf(children[i])) continue; - toggleClass(children[i], options.selectedClass, true); - multiDragElements.push(children[i]); - dispatchEvent({ - sortable: sortable, - rootEl: rootEl, - name: 'select', - targetEl: children[i], - originalEvent: evt - }); - } + (function () { + // Must include lastMultiDragSelect (select it), in case modified selection from no selection + // (but previous selection existed) + var n, i; + if (currentIndex > lastIndex) { + i = lastIndex; + n = currentIndex; + } else { + i = currentIndex; + n = lastIndex + 1; + } + var filter = options.filter; + for (; i < n; i++) { + if (~multiDragElements.indexOf(children[i])) continue; + // Check if element is draggable + if (!closest(children[i], options.draggable, parentEl, false)) continue; + // Check if element is filtered + var filtered = filter && (typeof filter === 'function' ? filter.call(sortable, evt, children[i], sortable) : filter.split(',').some(function (criteria) { + return closest(children[i], criteria.trim(), parentEl, false); + })); + if (filtered) continue; + toggleClass(children[i], options.selectedClass, true); + multiDragElements.push(children[i]); + dispatchEvent({ + sortable: sortable, + rootEl: rootEl, + name: 'select', + targetEl: children[i], + originalEvent: evt + }); + } + })(); } } else { lastMultiDragSelect = dragEl$1; diff --git a/Sortable.min.js b/Sortable.min.js index bb9953355..95423a649 100644 --- a/Sortable.min.js +++ b/Sortable.min.js @@ -1,2 +1,2 @@ -/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;tt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientYt.length)&&(e=t.length);for(var n=0,o=new Array(e);n"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function g(t){return t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&f(t,e)||o&&t===n)return t}while(t!==n&&(t=g(t)))}return null}var m,v=/\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(v," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(v," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function b(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function D(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Ft(t){Z&&Z.parentNode[K]._isOutsideThisEl(t.target)}function jt(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return kt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==jt.supportPointer&&"PointerEvent"in window&&(!u||c),emptyInsertThreshold:5};for(n in z.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in Rt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&It,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),St.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,A())}function Ht(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Lt(t){t.draggable=!1}function Kt(){xt=!1}function Wt(t){return setTimeout(t,0)}function zt(t){return clearTimeout(t)}jt.prototype={constructor:jt,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(vt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,Z):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){Ot.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&Ot.push(o)}}(o),!Z&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||et===l)){if(it=j(l),at=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return V({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),U("filter",n,{evt:e}),void(i&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return V({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),U("filter",n,{evt:e}),!0}))return void(i&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!Z&&n.parentNode===r&&(o=X(n),J=r,$=(Z=n).parentNode,tt=Z.nextSibling,et=n,st=a.group,ut={target:jt.dragged=Z,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ut.clientX-o.left,gt=ut.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,Z.style["will-change"]="all",o=function(){U("delayEnded",i,{evt:t}),jt.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(Z.draggable=!0),i._triggerDragStart(t,e),V({sortable:i,name:"choose",originalEvent:t}),k(Z,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){D(Z,t.trim(),Lt)}),h(l,"dragover",Bt),h(l,"mousemove",Bt),h(l,"touchmove",Bt),a.supportPointer?(h(l,"pointerup",i._onDrop),this.nativeDraggable||h(l,"pointercancel",i._onDrop)):(h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop)),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,Z.draggable=!0),U("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():jt.eventCanceled?this._onDrop():(a.supportPointer?(h(l,"pointerup",i._disableDelayedDrag),h(l,"pointercancel",i._disableDelayedDrag)):(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag)),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){Z&&Lt(Z),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;p(t,"mouseup",this._disableDelayedDrag),p(t,"touchend",this._disableDelayedDrag),p(t,"touchcancel",this._disableDelayedDrag),p(t,"pointerup",this._disableDelayedDrag),p(t,"pointercancel",this._disableDelayedDrag),p(t,"mousemove",this._delayedDragTouchMoveHandler),p(t,"touchmove",this._delayedDragTouchMoveHandler),p(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(Z,"dragend",this),h(J,"dragstart",this._onDragStart));try{document.selection?Wt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;Dt=!1,J&&Z?(U("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Ft),n=this.options,t||k(Z,n.dragClass,!1),k(Z,n.ghostClass,!0),jt.active=this,t&&this._appendGhost(),V({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(dt){this._lastX=dt.clientX,this._lastY=dt.clientY,Xt();for(var t=document.elementFromPoint(dt.clientX,dt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(dt.clientX,dt.clientY))!==e;)e=t;if(Z.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:dt.clientX,clientY:dt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=g(t=e));Yt()}},_onTouchMove:function(t){if(ut){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=Q&&b(Q,!0),a=Q&&r&&r.a,l=Q&&r&&r.d,e=At&&wt&&E(wt),a=(i.clientX-ut.clientX+o.x)/(a||1)+(e?e[0]-Tt[0]:0)/(a||1),l=(i.clientY-ut.clientY+o.y)/(l||1)+(e?e[1]-Tt[1]:0)/(l||1);if(!jt.active&&!Dt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))E.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>E.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,Q),e?t.clientX<_.left-10||t.clientY