sortable-rails 1.4.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 78756c7fc09d9830ebd40dd4b7171301d1526779
4
+ data.tar.gz: 8f99d9b89bbdec242c7decb1c4afdd829b5d2882
5
+ SHA512:
6
+ metadata.gz: c83d975e82a07acf27b1da06a076dc526adec2b2b06267c0c9430948a64b9f632a4d6c4f118e1230a655d769add7e7df9efd6dbeff629c1d4ce419dbc16d87f9
7
+ data.tar.gz: 715ad433a65259c5a713ee422f87ede2f1035b4a35ab7ac8408f7e0ad750da107570586650dc3a2d23b46c0ee6614078a285a140c0672f0238b1c0b2eb04a071
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at otaq.hsc@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sortable-rails.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Daryl Chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # Sortable::Rails
2
+
3
+ This gem packages the https://github.com/RubaXa/Sortable for Rails's assets pipeline
4
+
5
+ Sortable is a minimalist JavaScript library for reorderable drag-and-drop lists.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ``` ruby
12
+ gem 'sortable-rails'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```
18
+ $ bundle install
19
+ ```
20
+
21
+ In app/assets/javascripts/application.js, you should add as follows:
22
+
23
+ ```
24
+ //= require ...
25
+ //= require sortable-rails
26
+ //= require_tree .
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ See https://github.com/RubaXa/Sortable
32
+
33
+ ## License
34
+
35
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,8 @@
1
+ require "sortable/rails/version"
2
+
3
+ module Sortable
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Sortable
2
+ module Rails
3
+ VERSION = "1.4.2.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sortable/rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sortable-rails"
8
+ spec.version = Sortable::Rails::VERSION
9
+ spec.authors = ["Daryl Chen"]
10
+ spec.email = ["otaq.hsc@gmail.com"]
11
+
12
+ spec.summary = %q{Gemify Rubaxa's Sortable for Ruby on Rails}
13
+ spec.description = %q{This gem packages the Rubaxa's Sortable for Rails's assets pipeline}
14
+ spec.homepage = "https://github.com/otaq/sortable-rails/"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ end
@@ -0,0 +1,1271 @@
1
+ /**!
2
+ * Sortable
3
+ * @author RubaXa <trash@rubaxa.org>
4
+ * @license MIT
5
+ */
6
+
7
+
8
+ (function (factory) {
9
+ "use strict";
10
+
11
+ if (typeof define === "function" && define.amd) {
12
+ define(factory);
13
+ }
14
+ else if (typeof module != "undefined" && typeof module.exports != "undefined") {
15
+ module.exports = factory();
16
+ }
17
+ else if (typeof Package !== "undefined") {
18
+ Sortable = factory(); // export for Meteor.js
19
+ }
20
+ else {
21
+ /* jshint sub:true */
22
+ window["Sortable"] = factory();
23
+ }
24
+ })(function () {
25
+ "use strict";
26
+
27
+ if (typeof window == "undefined" || typeof window.document == "undefined") {
28
+ return function() {
29
+ throw new Error( "Sortable.js requires a window with a document" );
30
+ }
31
+ }
32
+
33
+ var dragEl,
34
+ parentEl,
35
+ ghostEl,
36
+ cloneEl,
37
+ rootEl,
38
+ nextEl,
39
+
40
+ scrollEl,
41
+ scrollParentEl,
42
+
43
+ lastEl,
44
+ lastCSS,
45
+ lastParentCSS,
46
+
47
+ oldIndex,
48
+ newIndex,
49
+
50
+ activeGroup,
51
+ autoScroll = {},
52
+
53
+ tapEvt,
54
+ touchEvt,
55
+
56
+ moved,
57
+
58
+ /** @const */
59
+ RSPACE = /\s+/g,
60
+
61
+ expando = 'Sortable' + (new Date).getTime(),
62
+
63
+ win = window,
64
+ document = win.document,
65
+ parseInt = win.parseInt,
66
+
67
+ supportDraggable = !!('draggable' in document.createElement('div')),
68
+ supportCssPointerEvents = (function (el) {
69
+ el = document.createElement('x');
70
+ el.style.cssText = 'pointer-events:auto';
71
+ return el.style.pointerEvents === 'auto';
72
+ })(),
73
+
74
+ _silent = false,
75
+
76
+ abs = Math.abs,
77
+ slice = [].slice,
78
+
79
+ touchDragOverListeners = [],
80
+
81
+ _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) {
82
+ // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
83
+ if (rootEl && options.scroll) {
84
+ var el,
85
+ rect,
86
+ sens = options.scrollSensitivity,
87
+ speed = options.scrollSpeed,
88
+
89
+ x = evt.clientX,
90
+ y = evt.clientY,
91
+
92
+ winWidth = window.innerWidth,
93
+ winHeight = window.innerHeight,
94
+
95
+ vx,
96
+ vy
97
+ ;
98
+
99
+ // Delect scrollEl
100
+ if (scrollParentEl !== rootEl) {
101
+ scrollEl = options.scroll;
102
+ scrollParentEl = rootEl;
103
+
104
+ if (scrollEl === true) {
105
+ scrollEl = rootEl;
106
+
107
+ do {
108
+ if ((scrollEl.offsetWidth < scrollEl.scrollWidth) ||
109
+ (scrollEl.offsetHeight < scrollEl.scrollHeight)
110
+ ) {
111
+ break;
112
+ }
113
+ /* jshint boss:true */
114
+ } while (scrollEl = scrollEl.parentNode);
115
+ }
116
+ }
117
+
118
+ if (scrollEl) {
119
+ el = scrollEl;
120
+ rect = scrollEl.getBoundingClientRect();
121
+ vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens);
122
+ vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens);
123
+ }
124
+
125
+
126
+ if (!(vx || vy)) {
127
+ vx = (winWidth - x <= sens) - (x <= sens);
128
+ vy = (winHeight - y <= sens) - (y <= sens);
129
+
130
+ /* jshint expr:true */
131
+ (vx || vy) && (el = win);
132
+ }
133
+
134
+
135
+ if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) {
136
+ autoScroll.el = el;
137
+ autoScroll.vx = vx;
138
+ autoScroll.vy = vy;
139
+
140
+ clearInterval(autoScroll.pid);
141
+
142
+ if (el) {
143
+ autoScroll.pid = setInterval(function () {
144
+ if (el === win) {
145
+ win.scrollTo(win.pageXOffset + vx * speed, win.pageYOffset + vy * speed);
146
+ } else {
147
+ vy && (el.scrollTop += vy * speed);
148
+ vx && (el.scrollLeft += vx * speed);
149
+ }
150
+ }, 24);
151
+ }
152
+ }
153
+ }
154
+ }, 30),
155
+
156
+ _prepareGroup = function (options) {
157
+ var group = options.group;
158
+
159
+ if (!group || typeof group != 'object') {
160
+ group = options.group = {name: group};
161
+ }
162
+
163
+ ['pull', 'put'].forEach(function (key) {
164
+ if (!(key in group)) {
165
+ group[key] = true;
166
+ }
167
+ });
168
+
169
+ options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' ';
170
+ }
171
+ ;
172
+
173
+
174
+
175
+ /**
176
+ * @class Sortable
177
+ * @param {HTMLElement} el
178
+ * @param {Object} [options]
179
+ */
180
+ function Sortable(el, options) {
181
+ if (!(el && el.nodeType && el.nodeType === 1)) {
182
+ throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el);
183
+ }
184
+
185
+ this.el = el; // root element
186
+ this.options = options = _extend({}, options);
187
+
188
+
189
+ // Export instance
190
+ el[expando] = this;
191
+
192
+
193
+ // Default options
194
+ var defaults = {
195
+ group: Math.random(),
196
+ sort: true,
197
+ disabled: false,
198
+ store: null,
199
+ handle: null,
200
+ scroll: true,
201
+ scrollSensitivity: 30,
202
+ scrollSpeed: 10,
203
+ draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*',
204
+ ghostClass: 'sortable-ghost',
205
+ chosenClass: 'sortable-chosen',
206
+ ignore: 'a, img',
207
+ filter: null,
208
+ animation: 0,
209
+ setData: function (dataTransfer, dragEl) {
210
+ dataTransfer.setData('Text', dragEl.textContent);
211
+ },
212
+ dropBubble: false,
213
+ dragoverBubble: false,
214
+ dataIdAttr: 'data-id',
215
+ delay: 0,
216
+ forceFallback: false,
217
+ fallbackClass: 'sortable-fallback',
218
+ fallbackOnBody: false
219
+ };
220
+
221
+
222
+ // Set default options
223
+ for (var name in defaults) {
224
+ !(name in options) && (options[name] = defaults[name]);
225
+ }
226
+
227
+ _prepareGroup(options);
228
+
229
+ // Bind all private methods
230
+ for (var fn in this) {
231
+ if (fn.charAt(0) === '_') {
232
+ this[fn] = this[fn].bind(this);
233
+ }
234
+ }
235
+
236
+ // Setup drag mode
237
+ this.nativeDraggable = options.forceFallback ? false : supportDraggable;
238
+
239
+ // Bind events
240
+ _on(el, 'mousedown', this._onTapStart);
241
+ _on(el, 'touchstart', this._onTapStart);
242
+
243
+ if (this.nativeDraggable) {
244
+ _on(el, 'dragover', this);
245
+ _on(el, 'dragenter', this);
246
+ }
247
+
248
+ touchDragOverListeners.push(this._onDragOver);
249
+
250
+ // Restore sorting
251
+ options.store && this.sort(options.store.get(this));
252
+ }
253
+
254
+
255
+ Sortable.prototype = /** @lends Sortable.prototype */ {
256
+ constructor: Sortable,
257
+
258
+ _onTapStart: function (/** Event|TouchEvent */evt) {
259
+ var _this = this,
260
+ el = this.el,
261
+ options = this.options,
262
+ type = evt.type,
263
+ touch = evt.touches && evt.touches[0],
264
+ target = (touch || evt).target,
265
+ originalTarget = target,
266
+ filter = options.filter;
267
+
268
+
269
+ if (type === 'mousedown' && evt.button !== 0 || options.disabled) {
270
+ return; // only left button or enabled
271
+ }
272
+
273
+ target = _closest(target, options.draggable, el);
274
+
275
+ if (!target) {
276
+ return;
277
+ }
278
+
279
+ // get the index of the dragged element within its parent
280
+ oldIndex = _index(target, options.draggable);
281
+
282
+ // Check filter
283
+ if (typeof filter === 'function') {
284
+ if (filter.call(this, evt, target, this)) {
285
+ _dispatchEvent(_this, originalTarget, 'filter', target, el, oldIndex);
286
+ evt.preventDefault();
287
+ return; // cancel dnd
288
+ }
289
+ }
290
+ else if (filter) {
291
+ filter = filter.split(',').some(function (criteria) {
292
+ criteria = _closest(originalTarget, criteria.trim(), el);
293
+
294
+ if (criteria) {
295
+ _dispatchEvent(_this, criteria, 'filter', target, el, oldIndex);
296
+ return true;
297
+ }
298
+ });
299
+
300
+ if (filter) {
301
+ evt.preventDefault();
302
+ return; // cancel dnd
303
+ }
304
+ }
305
+
306
+
307
+ if (options.handle && !_closest(originalTarget, options.handle, el)) {
308
+ return;
309
+ }
310
+
311
+
312
+ // Prepare `dragstart`
313
+ this._prepareDragStart(evt, touch, target);
314
+ },
315
+
316
+ _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target) {
317
+ var _this = this,
318
+ el = _this.el,
319
+ options = _this.options,
320
+ ownerDocument = el.ownerDocument,
321
+ dragStartFn;
322
+
323
+ if (target && !dragEl && (target.parentNode === el)) {
324
+ tapEvt = evt;
325
+
326
+ rootEl = el;
327
+ dragEl = target;
328
+ parentEl = dragEl.parentNode;
329
+ nextEl = dragEl.nextSibling;
330
+ activeGroup = options.group;
331
+
332
+ dragStartFn = function () {
333
+ // Delayed drag has been triggered
334
+ // we can re-enable the events: touchmove/mousemove
335
+ _this._disableDelayedDrag();
336
+
337
+ // Make the element draggable
338
+ dragEl.draggable = true;
339
+
340
+ // Chosen item
341
+ _toggleClass(dragEl, _this.options.chosenClass, true);
342
+
343
+ // Bind the events: dragstart/dragend
344
+ _this._triggerDragStart(touch);
345
+ };
346
+
347
+ // Disable "draggable"
348
+ options.ignore.split(',').forEach(function (criteria) {
349
+ _find(dragEl, criteria.trim(), _disableDraggable);
350
+ });
351
+
352
+ _on(ownerDocument, 'mouseup', _this._onDrop);
353
+ _on(ownerDocument, 'touchend', _this._onDrop);
354
+ _on(ownerDocument, 'touchcancel', _this._onDrop);
355
+
356
+ if (options.delay) {
357
+ // If the user moves the pointer or let go the click or touch
358
+ // before the delay has been reached:
359
+ // disable the delayed drag
360
+ _on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
361
+ _on(ownerDocument, 'touchend', _this._disableDelayedDrag);
362
+ _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
363
+ _on(ownerDocument, 'mousemove', _this._disableDelayedDrag);
364
+ _on(ownerDocument, 'touchmove', _this._disableDelayedDrag);
365
+
366
+ _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
367
+ } else {
368
+ dragStartFn();
369
+ }
370
+ }
371
+ },
372
+
373
+ _disableDelayedDrag: function () {
374
+ var ownerDocument = this.el.ownerDocument;
375
+
376
+ clearTimeout(this._dragStartTimer);
377
+ _off(ownerDocument, 'mouseup', this._disableDelayedDrag);
378
+ _off(ownerDocument, 'touchend', this._disableDelayedDrag);
379
+ _off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
380
+ _off(ownerDocument, 'mousemove', this._disableDelayedDrag);
381
+ _off(ownerDocument, 'touchmove', this._disableDelayedDrag);
382
+ },
383
+
384
+ _triggerDragStart: function (/** Touch */touch) {
385
+ if (touch) {
386
+ // Touch device support
387
+ tapEvt = {
388
+ target: dragEl,
389
+ clientX: touch.clientX,
390
+ clientY: touch.clientY
391
+ };
392
+
393
+ this._onDragStart(tapEvt, 'touch');
394
+ }
395
+ else if (!this.nativeDraggable) {
396
+ this._onDragStart(tapEvt, true);
397
+ }
398
+ else {
399
+ _on(dragEl, 'dragend', this);
400
+ _on(rootEl, 'dragstart', this._onDragStart);
401
+ }
402
+
403
+ try {
404
+ if (document.selection) {
405
+ document.selection.empty();
406
+ } else {
407
+ window.getSelection().removeAllRanges();
408
+ }
409
+ } catch (err) {
410
+ }
411
+ },
412
+
413
+ _dragStarted: function () {
414
+ if (rootEl && dragEl) {
415
+ // Apply effect
416
+ _toggleClass(dragEl, this.options.ghostClass, true);
417
+
418
+ Sortable.active = this;
419
+
420
+ // Drag start event
421
+ _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex);
422
+ }
423
+ },
424
+
425
+ _emulateDragOver: function () {
426
+ if (touchEvt) {
427
+ if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) {
428
+ return;
429
+ }
430
+
431
+ this._lastX = touchEvt.clientX;
432
+ this._lastY = touchEvt.clientY;
433
+
434
+ if (!supportCssPointerEvents) {
435
+ _css(ghostEl, 'display', 'none');
436
+ }
437
+
438
+ var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY),
439
+ parent = target,
440
+ groupName = ' ' + this.options.group.name + '',
441
+ i = touchDragOverListeners.length;
442
+
443
+ if (parent) {
444
+ do {
445
+ if (parent[expando] && parent[expando].options.groups.indexOf(groupName) > -1) {
446
+ while (i--) {
447
+ touchDragOverListeners[i]({
448
+ clientX: touchEvt.clientX,
449
+ clientY: touchEvt.clientY,
450
+ target: target,
451
+ rootEl: parent
452
+ });
453
+ }
454
+
455
+ break;
456
+ }
457
+
458
+ target = parent; // store last element
459
+ }
460
+ /* jshint boss:true */
461
+ while (parent = parent.parentNode);
462
+ }
463
+
464
+ if (!supportCssPointerEvents) {
465
+ _css(ghostEl, 'display', '');
466
+ }
467
+ }
468
+ },
469
+
470
+
471
+ _onTouchMove: function (/**TouchEvent*/evt) {
472
+ if (tapEvt) {
473
+ // only set the status to dragging, when we are actually dragging
474
+ if (!Sortable.active) {
475
+ this._dragStarted();
476
+ }
477
+
478
+ // as well as creating the ghost element on the document body
479
+ this._appendGhost();
480
+
481
+ var touch = evt.touches ? evt.touches[0] : evt,
482
+ dx = touch.clientX - tapEvt.clientX,
483
+ dy = touch.clientY - tapEvt.clientY,
484
+ translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)';
485
+
486
+ moved = true;
487
+ touchEvt = touch;
488
+
489
+ _css(ghostEl, 'webkitTransform', translate3d);
490
+ _css(ghostEl, 'mozTransform', translate3d);
491
+ _css(ghostEl, 'msTransform', translate3d);
492
+ _css(ghostEl, 'transform', translate3d);
493
+
494
+ evt.preventDefault();
495
+ }
496
+ },
497
+
498
+ _appendGhost: function () {
499
+ if (!ghostEl) {
500
+ var rect = dragEl.getBoundingClientRect(),
501
+ css = _css(dragEl),
502
+ options = this.options,
503
+ ghostRect;
504
+
505
+ ghostEl = dragEl.cloneNode(true);
506
+
507
+ _toggleClass(ghostEl, options.ghostClass, false);
508
+ _toggleClass(ghostEl, options.fallbackClass, true);
509
+
510
+ _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10));
511
+ _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10));
512
+ _css(ghostEl, 'width', rect.width);
513
+ _css(ghostEl, 'height', rect.height);
514
+ _css(ghostEl, 'opacity', '0.8');
515
+ _css(ghostEl, 'position', 'fixed');
516
+ _css(ghostEl, 'zIndex', '100000');
517
+ _css(ghostEl, 'pointerEvents', 'none');
518
+
519
+ options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl);
520
+
521
+ // Fixing dimensions.
522
+ ghostRect = ghostEl.getBoundingClientRect();
523
+ _css(ghostEl, 'width', rect.width * 2 - ghostRect.width);
524
+ _css(ghostEl, 'height', rect.height * 2 - ghostRect.height);
525
+ }
526
+ },
527
+
528
+ _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) {
529
+ var dataTransfer = evt.dataTransfer,
530
+ options = this.options;
531
+
532
+ this._offUpEvents();
533
+
534
+ if (activeGroup.pull == 'clone') {
535
+ cloneEl = dragEl.cloneNode(true);
536
+ _css(cloneEl, 'display', 'none');
537
+ rootEl.insertBefore(cloneEl, dragEl);
538
+ }
539
+
540
+ if (useFallback) {
541
+
542
+ if (useFallback === 'touch') {
543
+ // Bind touch events
544
+ _on(document, 'touchmove', this._onTouchMove);
545
+ _on(document, 'touchend', this._onDrop);
546
+ _on(document, 'touchcancel', this._onDrop);
547
+ } else {
548
+ // Old brwoser
549
+ _on(document, 'mousemove', this._onTouchMove);
550
+ _on(document, 'mouseup', this._onDrop);
551
+ }
552
+
553
+ this._loopId = setInterval(this._emulateDragOver, 50);
554
+ }
555
+ else {
556
+ if (dataTransfer) {
557
+ dataTransfer.effectAllowed = 'move';
558
+ options.setData && options.setData.call(this, dataTransfer, dragEl);
559
+ }
560
+
561
+ _on(document, 'drop', this);
562
+ setTimeout(this._dragStarted, 0);
563
+ }
564
+ },
565
+
566
+ _onDragOver: function (/**Event*/evt) {
567
+ var el = this.el,
568
+ target,
569
+ dragRect,
570
+ revert,
571
+ options = this.options,
572
+ group = options.group,
573
+ groupPut = group.put,
574
+ isOwner = (activeGroup === group),
575
+ canSort = options.sort;
576
+
577
+ if (evt.preventDefault !== void 0) {
578
+ evt.preventDefault();
579
+ !options.dragoverBubble && evt.stopPropagation();
580
+ }
581
+
582
+ moved = true;
583
+
584
+ if (activeGroup && !options.disabled &&
585
+ (isOwner
586
+ ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
587
+ : activeGroup.pull && groupPut && (
588
+ (activeGroup.name === group.name) || // by Name
589
+ (groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array
590
+ )
591
+ ) &&
592
+ (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback
593
+ ) {
594
+ // Smart auto-scrolling
595
+ _autoScroll(evt, options, this.el);
596
+
597
+ if (_silent) {
598
+ return;
599
+ }
600
+
601
+ target = _closest(evt.target, options.draggable, el);
602
+ dragRect = dragEl.getBoundingClientRect();
603
+
604
+ if (revert) {
605
+ _cloneHide(true);
606
+
607
+ if (cloneEl || nextEl) {
608
+ rootEl.insertBefore(dragEl, cloneEl || nextEl);
609
+ }
610
+ else if (!canSort) {
611
+ rootEl.appendChild(dragEl);
612
+ }
613
+
614
+ return;
615
+ }
616
+
617
+
618
+ if ((el.children.length === 0) || (el.children[0] === ghostEl) ||
619
+ (el === evt.target) && (target = _ghostIsLast(el, evt))
620
+ ) {
621
+
622
+ if (target) {
623
+ if (target.animated) {
624
+ return;
625
+ }
626
+
627
+ targetRect = target.getBoundingClientRect();
628
+ }
629
+
630
+ _cloneHide(isOwner);
631
+
632
+ if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) {
633
+ if (!dragEl.contains(el)) {
634
+ el.appendChild(dragEl);
635
+ parentEl = el; // actualization
636
+ }
637
+
638
+ this._animate(dragRect, dragEl);
639
+ target && this._animate(targetRect, target);
640
+ }
641
+ }
642
+ else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) {
643
+ if (lastEl !== target) {
644
+ lastEl = target;
645
+ lastCSS = _css(target);
646
+ lastParentCSS = _css(target.parentNode);
647
+ }
648
+
649
+
650
+ var targetRect = target.getBoundingClientRect(),
651
+ width = targetRect.right - targetRect.left,
652
+ height = targetRect.bottom - targetRect.top,
653
+ floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display)
654
+ || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0),
655
+ isWide = (target.offsetWidth > dragEl.offsetWidth),
656
+ isLong = (target.offsetHeight > dragEl.offsetHeight),
657
+ halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5,
658
+ nextSibling = target.nextElementSibling,
659
+ moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect),
660
+ after
661
+ ;
662
+
663
+ if (moveVector !== false) {
664
+ _silent = true;
665
+ setTimeout(_unsilent, 30);
666
+
667
+ _cloneHide(isOwner);
668
+
669
+ if (moveVector === 1 || moveVector === -1) {
670
+ after = (moveVector === 1);
671
+ }
672
+ else if (floating) {
673
+ var elTop = dragEl.offsetTop,
674
+ tgTop = target.offsetTop;
675
+
676
+ if (elTop === tgTop) {
677
+ after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
678
+ } else {
679
+ after = tgTop > elTop;
680
+ }
681
+ } else {
682
+ after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
683
+ }
684
+
685
+ if (!dragEl.contains(el)) {
686
+ if (after && !nextSibling) {
687
+ el.appendChild(dragEl);
688
+ } else {
689
+ target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
690
+ }
691
+ }
692
+
693
+ parentEl = dragEl.parentNode; // actualization
694
+
695
+ this._animate(dragRect, dragEl);
696
+ this._animate(targetRect, target);
697
+ }
698
+ }
699
+ }
700
+ },
701
+
702
+ _animate: function (prevRect, target) {
703
+ var ms = this.options.animation;
704
+
705
+ if (ms) {
706
+ var currentRect = target.getBoundingClientRect();
707
+
708
+ _css(target, 'transition', 'none');
709
+ _css(target, 'transform', 'translate3d('
710
+ + (prevRect.left - currentRect.left) + 'px,'
711
+ + (prevRect.top - currentRect.top) + 'px,0)'
712
+ );
713
+
714
+ target.offsetWidth; // repaint
715
+
716
+ _css(target, 'transition', 'all ' + ms + 'ms');
717
+ _css(target, 'transform', 'translate3d(0,0,0)');
718
+
719
+ clearTimeout(target.animated);
720
+ target.animated = setTimeout(function () {
721
+ _css(target, 'transition', '');
722
+ _css(target, 'transform', '');
723
+ target.animated = false;
724
+ }, ms);
725
+ }
726
+ },
727
+
728
+ _offUpEvents: function () {
729
+ var ownerDocument = this.el.ownerDocument;
730
+
731
+ _off(document, 'touchmove', this._onTouchMove);
732
+ _off(ownerDocument, 'mouseup', this._onDrop);
733
+ _off(ownerDocument, 'touchend', this._onDrop);
734
+ _off(ownerDocument, 'touchcancel', this._onDrop);
735
+ },
736
+
737
+ _onDrop: function (/**Event*/evt) {
738
+ var el = this.el,
739
+ options = this.options;
740
+
741
+ clearInterval(this._loopId);
742
+ clearInterval(autoScroll.pid);
743
+ clearTimeout(this._dragStartTimer);
744
+
745
+ // Unbind events
746
+ _off(document, 'mousemove', this._onTouchMove);
747
+
748
+ if (this.nativeDraggable) {
749
+ _off(document, 'drop', this);
750
+ _off(el, 'dragstart', this._onDragStart);
751
+ }
752
+
753
+ this._offUpEvents();
754
+
755
+ if (evt) {
756
+ if (moved) {
757
+ evt.preventDefault();
758
+ !options.dropBubble && evt.stopPropagation();
759
+ }
760
+
761
+ ghostEl && ghostEl.parentNode.removeChild(ghostEl);
762
+
763
+ if (dragEl) {
764
+ if (this.nativeDraggable) {
765
+ _off(dragEl, 'dragend', this);
766
+ }
767
+
768
+ _disableDraggable(dragEl);
769
+
770
+ // Remove class's
771
+ _toggleClass(dragEl, this.options.ghostClass, false);
772
+ _toggleClass(dragEl, this.options.chosenClass, false);
773
+
774
+ if (rootEl !== parentEl) {
775
+ newIndex = _index(dragEl, options.draggable);
776
+
777
+ if (newIndex >= 0) {
778
+ // drag from one list and drop into another
779
+ _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
780
+ _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
781
+
782
+ // Add event
783
+ _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex);
784
+
785
+ // Remove event
786
+ _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex);
787
+ }
788
+ }
789
+ else {
790
+ // Remove clone
791
+ cloneEl && cloneEl.parentNode.removeChild(cloneEl);
792
+
793
+ if (dragEl.nextSibling !== nextEl) {
794
+ // Get the index of the dragged element within its parent
795
+ newIndex = _index(dragEl, options.draggable);
796
+
797
+ if (newIndex >= 0) {
798
+ // drag & drop within the same list
799
+ _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex);
800
+ _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
801
+ }
802
+ }
803
+ }
804
+
805
+ if (Sortable.active) {
806
+ if (newIndex === null || newIndex === -1) {
807
+ newIndex = oldIndex;
808
+ }
809
+
810
+ _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex);
811
+
812
+ // Save sorting
813
+ this.save();
814
+ }
815
+ }
816
+
817
+ }
818
+ this._nulling();
819
+ },
820
+
821
+ _nulling: function() {
822
+ // Nulling
823
+ rootEl =
824
+ dragEl =
825
+ parentEl =
826
+ ghostEl =
827
+ nextEl =
828
+ cloneEl =
829
+
830
+ scrollEl =
831
+ scrollParentEl =
832
+
833
+ tapEvt =
834
+ touchEvt =
835
+
836
+ moved =
837
+ newIndex =
838
+
839
+ lastEl =
840
+ lastCSS =
841
+
842
+ activeGroup =
843
+ Sortable.active = null;
844
+ },
845
+
846
+ handleEvent: function (/**Event*/evt) {
847
+ var type = evt.type;
848
+
849
+ if (type === 'dragover' || type === 'dragenter') {
850
+ if (dragEl) {
851
+ this._onDragOver(evt);
852
+ _globalDragOver(evt);
853
+ }
854
+ }
855
+ else if (type === 'drop' || type === 'dragend') {
856
+ this._onDrop(evt);
857
+ }
858
+ },
859
+
860
+
861
+ /**
862
+ * Serializes the item into an array of string.
863
+ * @returns {String[]}
864
+ */
865
+ toArray: function () {
866
+ var order = [],
867
+ el,
868
+ children = this.el.children,
869
+ i = 0,
870
+ n = children.length,
871
+ options = this.options;
872
+
873
+ for (; i < n; i++) {
874
+ el = children[i];
875
+ if (_closest(el, options.draggable, this.el)) {
876
+ order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
877
+ }
878
+ }
879
+
880
+ return order;
881
+ },
882
+
883
+
884
+ /**
885
+ * Sorts the elements according to the array.
886
+ * @param {String[]} order order of the items
887
+ */
888
+ sort: function (order) {
889
+ var items = {}, rootEl = this.el;
890
+
891
+ this.toArray().forEach(function (id, i) {
892
+ var el = rootEl.children[i];
893
+
894
+ if (_closest(el, this.options.draggable, rootEl)) {
895
+ items[id] = el;
896
+ }
897
+ }, this);
898
+
899
+ order.forEach(function (id) {
900
+ if (items[id]) {
901
+ rootEl.removeChild(items[id]);
902
+ rootEl.appendChild(items[id]);
903
+ }
904
+ });
905
+ },
906
+
907
+
908
+ /**
909
+ * Save the current sorting
910
+ */
911
+ save: function () {
912
+ var store = this.options.store;
913
+ store && store.set(this);
914
+ },
915
+
916
+
917
+ /**
918
+ * 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.
919
+ * @param {HTMLElement} el
920
+ * @param {String} [selector] default: `options.draggable`
921
+ * @returns {HTMLElement|null}
922
+ */
923
+ closest: function (el, selector) {
924
+ return _closest(el, selector || this.options.draggable, this.el);
925
+ },
926
+
927
+
928
+ /**
929
+ * Set/get option
930
+ * @param {string} name
931
+ * @param {*} [value]
932
+ * @returns {*}
933
+ */
934
+ option: function (name, value) {
935
+ var options = this.options;
936
+
937
+ if (value === void 0) {
938
+ return options[name];
939
+ } else {
940
+ options[name] = value;
941
+
942
+ if (name === 'group') {
943
+ _prepareGroup(options);
944
+ }
945
+ }
946
+ },
947
+
948
+
949
+ /**
950
+ * Destroy
951
+ */
952
+ destroy: function () {
953
+ var el = this.el;
954
+
955
+ el[expando] = null;
956
+
957
+ _off(el, 'mousedown', this._onTapStart);
958
+ _off(el, 'touchstart', this._onTapStart);
959
+
960
+ if (this.nativeDraggable) {
961
+ _off(el, 'dragover', this);
962
+ _off(el, 'dragenter', this);
963
+ }
964
+
965
+ // Remove draggable attributes
966
+ Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
967
+ el.removeAttribute('draggable');
968
+ });
969
+
970
+ touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1);
971
+
972
+ this._onDrop();
973
+
974
+ this.el = el = null;
975
+ }
976
+ };
977
+
978
+
979
+ function _cloneHide(state) {
980
+ if (cloneEl && (cloneEl.state !== state)) {
981
+ _css(cloneEl, 'display', state ? 'none' : '');
982
+ !state && cloneEl.state && rootEl.insertBefore(cloneEl, dragEl);
983
+ cloneEl.state = state;
984
+ }
985
+ }
986
+
987
+
988
+ function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) {
989
+ if (el) {
990
+ ctx = ctx || document;
991
+
992
+ do {
993
+ if (
994
+ (selector === '>*' && el.parentNode === ctx)
995
+ || _matches(el, selector)
996
+ ) {
997
+ return el;
998
+ }
999
+ }
1000
+ while (el !== ctx && (el = el.parentNode));
1001
+ }
1002
+
1003
+ return null;
1004
+ }
1005
+
1006
+
1007
+ function _globalDragOver(/**Event*/evt) {
1008
+ if (evt.dataTransfer) {
1009
+ evt.dataTransfer.dropEffect = 'move';
1010
+ }
1011
+ evt.preventDefault();
1012
+ }
1013
+
1014
+
1015
+ function _on(el, event, fn) {
1016
+ el.addEventListener(event, fn, false);
1017
+ }
1018
+
1019
+
1020
+ function _off(el, event, fn) {
1021
+ el.removeEventListener(event, fn, false);
1022
+ }
1023
+
1024
+
1025
+ function _toggleClass(el, name, state) {
1026
+ if (el) {
1027
+ if (el.classList) {
1028
+ el.classList[state ? 'add' : 'remove'](name);
1029
+ }
1030
+ else {
1031
+ var className = (' ' + el.className + ' ').replace(RSPACE, ' ').replace(' ' + name + ' ', ' ');
1032
+ el.className = (className + (state ? ' ' + name : '')).replace(RSPACE, ' ');
1033
+ }
1034
+ }
1035
+ }
1036
+
1037
+
1038
+ function _css(el, prop, val) {
1039
+ var style = el && el.style;
1040
+
1041
+ if (style) {
1042
+ if (val === void 0) {
1043
+ if (document.defaultView && document.defaultView.getComputedStyle) {
1044
+ val = document.defaultView.getComputedStyle(el, '');
1045
+ }
1046
+ else if (el.currentStyle) {
1047
+ val = el.currentStyle;
1048
+ }
1049
+
1050
+ return prop === void 0 ? val : val[prop];
1051
+ }
1052
+ else {
1053
+ if (!(prop in style)) {
1054
+ prop = '-webkit-' + prop;
1055
+ }
1056
+
1057
+ style[prop] = val + (typeof val === 'string' ? '' : 'px');
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+
1063
+ function _find(ctx, tagName, iterator) {
1064
+ if (ctx) {
1065
+ var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length;
1066
+
1067
+ if (iterator) {
1068
+ for (; i < n; i++) {
1069
+ iterator(list[i], i);
1070
+ }
1071
+ }
1072
+
1073
+ return list;
1074
+ }
1075
+
1076
+ return [];
1077
+ }
1078
+
1079
+
1080
+
1081
+ function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
1082
+ var evt = document.createEvent('Event'),
1083
+ options = (sortable || rootEl[expando]).options,
1084
+ onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
1085
+
1086
+ evt.initEvent(name, true, true);
1087
+
1088
+ evt.to = rootEl;
1089
+ evt.from = fromEl || rootEl;
1090
+ evt.item = targetEl || rootEl;
1091
+ evt.clone = cloneEl;
1092
+
1093
+ evt.oldIndex = startIndex;
1094
+ evt.newIndex = newIndex;
1095
+
1096
+ rootEl.dispatchEvent(evt);
1097
+
1098
+ if (options[onName]) {
1099
+ options[onName].call(sortable, evt);
1100
+ }
1101
+ }
1102
+
1103
+
1104
+ function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) {
1105
+ var evt,
1106
+ sortable = fromEl[expando],
1107
+ onMoveFn = sortable.options.onMove,
1108
+ retVal;
1109
+
1110
+ evt = document.createEvent('Event');
1111
+ evt.initEvent('move', true, true);
1112
+
1113
+ evt.to = toEl;
1114
+ evt.from = fromEl;
1115
+ evt.dragged = dragEl;
1116
+ evt.draggedRect = dragRect;
1117
+ evt.related = targetEl || toEl;
1118
+ evt.relatedRect = targetRect || toEl.getBoundingClientRect();
1119
+
1120
+ fromEl.dispatchEvent(evt);
1121
+
1122
+ if (onMoveFn) {
1123
+ retVal = onMoveFn.call(sortable, evt);
1124
+ }
1125
+
1126
+ return retVal;
1127
+ }
1128
+
1129
+
1130
+ function _disableDraggable(el) {
1131
+ el.draggable = false;
1132
+ }
1133
+
1134
+
1135
+ function _unsilent() {
1136
+ _silent = false;
1137
+ }
1138
+
1139
+
1140
+ /** @returns {HTMLElement|false} */
1141
+ function _ghostIsLast(el, evt) {
1142
+ var lastEl = el.lastElementChild,
1143
+ rect = lastEl.getBoundingClientRect();
1144
+
1145
+ return ((evt.clientY - (rect.top + rect.height) > 5) || (evt.clientX - (rect.right + rect.width) > 5)) && lastEl; // min delta
1146
+ }
1147
+
1148
+
1149
+ /**
1150
+ * Generate id
1151
+ * @param {HTMLElement} el
1152
+ * @returns {String}
1153
+ * @private
1154
+ */
1155
+ function _generateId(el) {
1156
+ var str = el.tagName + el.className + el.src + el.href + el.textContent,
1157
+ i = str.length,
1158
+ sum = 0;
1159
+
1160
+ while (i--) {
1161
+ sum += str.charCodeAt(i);
1162
+ }
1163
+
1164
+ return sum.toString(36);
1165
+ }
1166
+
1167
+ /**
1168
+ * Returns the index of an element within its parent for a selected set of
1169
+ * elements
1170
+ * @param {HTMLElement} el
1171
+ * @param {selector} selector
1172
+ * @return {number}
1173
+ */
1174
+ function _index(el, selector) {
1175
+ var index = 0;
1176
+
1177
+ if (!el || !el.parentNode) {
1178
+ return -1;
1179
+ }
1180
+
1181
+ while (el && (el = el.previousElementSibling)) {
1182
+ if (el.nodeName.toUpperCase() !== 'TEMPLATE'
1183
+ && _matches(el, selector)) {
1184
+ index++;
1185
+ }
1186
+ }
1187
+
1188
+ return index;
1189
+ }
1190
+
1191
+ function _matches(/**HTMLElement*/el, /**String*/selector) {
1192
+ if (el) {
1193
+ selector = selector.split('.');
1194
+
1195
+ var tag = selector.shift().toUpperCase(),
1196
+ re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g');
1197
+
1198
+ return (
1199
+ (tag === '' || el.nodeName.toUpperCase() == tag) &&
1200
+ (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length)
1201
+ );
1202
+ }
1203
+
1204
+ return false;
1205
+ }
1206
+
1207
+ function _throttle(callback, ms) {
1208
+ var args, _this;
1209
+
1210
+ return function () {
1211
+ if (args === void 0) {
1212
+ args = arguments;
1213
+ _this = this;
1214
+
1215
+ setTimeout(function () {
1216
+ if (args.length === 1) {
1217
+ callback.call(_this, args[0]);
1218
+ } else {
1219
+ callback.apply(_this, args);
1220
+ }
1221
+
1222
+ args = void 0;
1223
+ }, ms);
1224
+ }
1225
+ };
1226
+ }
1227
+
1228
+ function _extend(dst, src) {
1229
+ if (dst && src) {
1230
+ for (var key in src) {
1231
+ if (src.hasOwnProperty(key)) {
1232
+ dst[key] = src[key];
1233
+ }
1234
+ }
1235
+ }
1236
+
1237
+ return dst;
1238
+ }
1239
+
1240
+
1241
+ // Export utils
1242
+ Sortable.utils = {
1243
+ on: _on,
1244
+ off: _off,
1245
+ css: _css,
1246
+ find: _find,
1247
+ is: function (el, selector) {
1248
+ return !!_closest(el, selector, el);
1249
+ },
1250
+ extend: _extend,
1251
+ throttle: _throttle,
1252
+ closest: _closest,
1253
+ toggleClass: _toggleClass,
1254
+ index: _index
1255
+ };
1256
+
1257
+
1258
+ /**
1259
+ * Create sortable instance
1260
+ * @param {HTMLElement} el
1261
+ * @param {Object} [options]
1262
+ */
1263
+ Sortable.create = function (el, options) {
1264
+ return new Sortable(el, options);
1265
+ };
1266
+
1267
+
1268
+ // Export
1269
+ Sortable.version = '1.4.2';
1270
+ return Sortable;
1271
+ });