pageflow 17.0.1 → 17.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1315 @@
1
+ /*!
2
+ * jQuery UI Sortable 1.11.4
3
+ * http://jqueryui.com
4
+ *
5
+ * Copyright jQuery Foundation and other contributors
6
+ * Released under the MIT license.
7
+ * http://jquery.org/license
8
+ *
9
+ * http://api.jqueryui.com/sortable/
10
+ */
11
+ (function( factory ) {
12
+ if ( typeof define === "function" && define.amd ) {
13
+
14
+ // AMD. Register as an anonymous module.
15
+ define([
16
+ "jquery",
17
+ "./core",
18
+ "./mouse",
19
+ "./widget"
20
+ ], factory );
21
+ } else {
22
+
23
+ // Browser globals
24
+ factory( require('jquery') );
25
+ }
26
+ }(function( $ ) {
27
+
28
+ return $.widget("ui.sortable", $.ui.mouse, {
29
+ version: "1.11.4",
30
+ widgetEventPrefix: "sort",
31
+ ready: false,
32
+ options: {
33
+ appendTo: "parent",
34
+ axis: false,
35
+ connectWith: false,
36
+ containment: false,
37
+ cursor: "auto",
38
+ cursorAt: false,
39
+ dropOnEmpty: true,
40
+ forcePlaceholderSize: false,
41
+ forceHelperSize: false,
42
+ grid: false,
43
+ handle: false,
44
+ helper: "original",
45
+ items: "> *",
46
+ opacity: false,
47
+ placeholder: false,
48
+ revert: false,
49
+ scroll: true,
50
+ scrollSensitivity: 20,
51
+ scrollSpeed: 20,
52
+ scope: "default",
53
+ tolerance: "intersect",
54
+ zIndex: 1000,
55
+
56
+ // callbacks
57
+ activate: null,
58
+ beforeStop: null,
59
+ change: null,
60
+ deactivate: null,
61
+ out: null,
62
+ over: null,
63
+ receive: null,
64
+ remove: null,
65
+ sort: null,
66
+ start: null,
67
+ stop: null,
68
+ update: null
69
+ },
70
+
71
+ _isOverAxis: function( x, reference, size ) {
72
+ return ( x >= reference ) && ( x < ( reference + size ) );
73
+ },
74
+
75
+ _isFloating: function( item ) {
76
+ return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
77
+ },
78
+
79
+ _create: function() {
80
+ this.containerCache = {};
81
+ this.element.addClass("ui-sortable");
82
+
83
+ //Get the items
84
+ this.refresh();
85
+
86
+ //Let's determine the parent's offset
87
+ this.offset = this.element.offset();
88
+
89
+ //Initialize mouse events for interaction
90
+ this._mouseInit();
91
+
92
+ this._setHandleClassName();
93
+
94
+ //We're ready to go
95
+ this.ready = true;
96
+
97
+ },
98
+
99
+ _setOption: function( key, value ) {
100
+ this._super( key, value );
101
+
102
+ if ( key === "handle" ) {
103
+ this._setHandleClassName();
104
+ }
105
+ },
106
+
107
+ _setHandleClassName: function() {
108
+ this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
109
+ $.each( this.items, function() {
110
+ ( this.instance.options.handle ?
111
+ this.item.find( this.instance.options.handle ) : this.item )
112
+ .addClass( "ui-sortable-handle" );
113
+ });
114
+ },
115
+
116
+ _destroy: function() {
117
+ this.element
118
+ .removeClass( "ui-sortable ui-sortable-disabled" )
119
+ .find( ".ui-sortable-handle" )
120
+ .removeClass( "ui-sortable-handle" );
121
+ this._mouseDestroy();
122
+
123
+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
124
+ this.items[i].item.removeData(this.widgetName + "-item");
125
+ }
126
+
127
+ return this;
128
+ },
129
+
130
+ _mouseCapture: function(event, overrideHandle) {
131
+ var currentItem = null,
132
+ validHandle = false,
133
+ that = this;
134
+
135
+ if (this.reverting) {
136
+ return false;
137
+ }
138
+
139
+ if(this.options.disabled || this.options.type === "static") {
140
+ return false;
141
+ }
142
+
143
+ //We have to refresh the items data once first
144
+ this._refreshItems(event);
145
+
146
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
147
+ $(event.target).parents().each(function() {
148
+ if($.data(this, that.widgetName + "-item") === that) {
149
+ currentItem = $(this);
150
+ return false;
151
+ }
152
+ });
153
+ if($.data(event.target, that.widgetName + "-item") === that) {
154
+ currentItem = $(event.target);
155
+ }
156
+
157
+ if(!currentItem) {
158
+ return false;
159
+ }
160
+ if(this.options.handle && !overrideHandle) {
161
+ $(this.options.handle, currentItem).find("*").addBack().each(function() {
162
+ if(this === event.target) {
163
+ validHandle = true;
164
+ }
165
+ });
166
+ if(!validHandle) {
167
+ return false;
168
+ }
169
+ }
170
+
171
+ this.currentItem = currentItem;
172
+ this._removeCurrentsFromItems();
173
+ return true;
174
+
175
+ },
176
+
177
+ _mouseStart: function(event, overrideHandle, noActivation) {
178
+
179
+ var i, body,
180
+ o = this.options;
181
+
182
+ this.currentContainer = this;
183
+
184
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
185
+ this.refreshPositions();
186
+
187
+ //Create and append the visible helper
188
+ this.helper = this._createHelper(event);
189
+
190
+ //Cache the helper size
191
+ this._cacheHelperProportions();
192
+
193
+ /*
194
+ * - Position generation -
195
+ * This block generates everything position related - it's the core of draggables.
196
+ */
197
+
198
+ //Cache the margins of the original element
199
+ this._cacheMargins();
200
+
201
+ //Get the next scrolling parent
202
+ this.scrollParent = this.helper.scrollParent();
203
+
204
+ //The element's absolute position on the page minus margins
205
+ this.offset = this.currentItem.offset();
206
+ this.offset = {
207
+ top: this.offset.top - this.margins.top,
208
+ left: this.offset.left - this.margins.left
209
+ };
210
+
211
+ $.extend(this.offset, {
212
+ click: { //Where the click happened, relative to the element
213
+ left: event.pageX - this.offset.left,
214
+ top: event.pageY - this.offset.top
215
+ },
216
+ parent: this._getParentOffset(),
217
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
218
+ });
219
+
220
+ // Only after we got the offset, we can change the helper's position to absolute
221
+ // TODO: Still need to figure out a way to make relative sorting possible
222
+ this.helper.css("position", "absolute");
223
+ this.cssPosition = this.helper.css("position");
224
+
225
+ //Generate the original position
226
+ this.originalPosition = this._generatePosition(event);
227
+ this.originalPageX = event.pageX;
228
+ this.originalPageY = event.pageY;
229
+
230
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
231
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
232
+
233
+ //Cache the former DOM position
234
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
235
+
236
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
237
+ if(this.helper[0] !== this.currentItem[0]) {
238
+ this.currentItem.hide();
239
+ }
240
+
241
+ //Create the placeholder
242
+ this._createPlaceholder();
243
+
244
+ //Set a containment if given in the options
245
+ if(o.containment) {
246
+ this._setContainment();
247
+ }
248
+
249
+ if( o.cursor && o.cursor !== "auto" ) { // cursor option
250
+ body = this.document.find( "body" );
251
+
252
+ // support: IE
253
+ this.storedCursor = body.css( "cursor" );
254
+ body.css( "cursor", o.cursor );
255
+
256
+ this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
257
+ }
258
+
259
+ if(o.opacity) { // opacity option
260
+ if (this.helper.css("opacity")) {
261
+ this._storedOpacity = this.helper.css("opacity");
262
+ }
263
+ this.helper.css("opacity", o.opacity);
264
+ }
265
+
266
+ if(o.zIndex) { // zIndex option
267
+ if (this.helper.css("zIndex")) {
268
+ this._storedZIndex = this.helper.css("zIndex");
269
+ }
270
+ this.helper.css("zIndex", o.zIndex);
271
+ }
272
+
273
+ //Prepare scrolling
274
+ if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
275
+ this.overflowOffset = this.scrollParent.offset();
276
+ }
277
+
278
+ //Call callbacks
279
+ this._trigger("start", event, this._uiHash());
280
+
281
+ //Recache the helper size
282
+ if(!this._preserveHelperProportions) {
283
+ this._cacheHelperProportions();
284
+ }
285
+
286
+
287
+ //Post "activate" events to possible containers
288
+ if( !noActivation ) {
289
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
290
+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
291
+ }
292
+ }
293
+
294
+ //Prepare possible droppables
295
+ if($.ui.ddmanager) {
296
+ $.ui.ddmanager.current = this;
297
+ }
298
+
299
+ if ($.ui.ddmanager && !o.dropBehaviour) {
300
+ $.ui.ddmanager.prepareOffsets(this, event);
301
+ }
302
+
303
+ this.dragging = true;
304
+
305
+ this.helper.addClass("ui-sortable-helper");
306
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
307
+ return true;
308
+
309
+ },
310
+
311
+ _mouseDrag: function(event) {
312
+ var i, item, itemElement, intersection,
313
+ o = this.options,
314
+ scrolled = false;
315
+
316
+ //Compute the helpers position
317
+ this.position = this._generatePosition(event);
318
+ this.positionAbs = this._convertPositionTo("absolute");
319
+
320
+ if (!this.lastPositionAbs) {
321
+ this.lastPositionAbs = this.positionAbs;
322
+ }
323
+
324
+ //Do scrolling
325
+ if(this.options.scroll) {
326
+ if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
327
+
328
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
329
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
330
+ } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
331
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
332
+ }
333
+
334
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
335
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
336
+ } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
337
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
338
+ }
339
+
340
+ } else {
341
+
342
+ if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
343
+ scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
344
+ } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
345
+ scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
346
+ }
347
+
348
+ if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
349
+ scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
350
+ } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
351
+ scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
352
+ }
353
+
354
+ }
355
+
356
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
357
+ $.ui.ddmanager.prepareOffsets(this, event);
358
+ }
359
+ }
360
+
361
+ //Regenerate the absolute position used for position checks
362
+ this.positionAbs = this._convertPositionTo("absolute");
363
+
364
+ //Set the helper position
365
+ if(!this.options.axis || this.options.axis !== "y") {
366
+ this.helper[0].style.left = this.position.left+"px";
367
+ }
368
+ if(!this.options.axis || this.options.axis !== "x") {
369
+ this.helper[0].style.top = this.position.top+"px";
370
+ }
371
+
372
+ //Rearrange
373
+ for (i = this.items.length - 1; i >= 0; i--) {
374
+
375
+ //Cache variables and intersection, continue if no intersection
376
+ item = this.items[i];
377
+ itemElement = item.item[0];
378
+ intersection = this._intersectsWithPointer(item);
379
+ if (!intersection) {
380
+ continue;
381
+ }
382
+
383
+ // Only put the placeholder inside the current Container, skip all
384
+ // items from other containers. This works because when moving
385
+ // an item from one container to another the
386
+ // currentContainer is switched before the placeholder is moved.
387
+ //
388
+ // Without this, moving items in "sub-sortables" can cause
389
+ // the placeholder to jitter between the outer and inner container.
390
+ if (item.instance !== this.currentContainer) {
391
+ continue;
392
+ }
393
+
394
+ // cannot intersect with itself
395
+ // no useless actions that have been done before
396
+ // no action if the item moved is the parent of the item checked
397
+ if (itemElement !== this.currentItem[0] &&
398
+ this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
399
+ !$.contains(this.placeholder[0], itemElement) &&
400
+ (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
401
+ ) {
402
+
403
+ this.direction = intersection === 1 ? "down" : "up";
404
+
405
+ if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
406
+ this._rearrange(event, item);
407
+ } else {
408
+ break;
409
+ }
410
+
411
+ this._trigger("change", event, this._uiHash());
412
+ break;
413
+ }
414
+ }
415
+
416
+ //Post events to containers
417
+ this._contactContainers(event);
418
+
419
+ //Interconnect with droppables
420
+ if($.ui.ddmanager) {
421
+ $.ui.ddmanager.drag(this, event);
422
+ }
423
+
424
+ //Call callbacks
425
+ this._trigger("sort", event, this._uiHash());
426
+
427
+ this.lastPositionAbs = this.positionAbs;
428
+ return false;
429
+
430
+ },
431
+
432
+ _mouseStop: function(event, noPropagation) {
433
+
434
+ if(!event) {
435
+ return;
436
+ }
437
+
438
+ //If we are using droppables, inform the manager about the drop
439
+ if ($.ui.ddmanager && !this.options.dropBehaviour) {
440
+ $.ui.ddmanager.drop(this, event);
441
+ }
442
+
443
+ if(this.options.revert) {
444
+ var that = this,
445
+ cur = this.placeholder.offset(),
446
+ axis = this.options.axis,
447
+ animation = {};
448
+
449
+ if ( !axis || axis === "x" ) {
450
+ animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
451
+ }
452
+ if ( !axis || axis === "y" ) {
453
+ animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
454
+ }
455
+ this.reverting = true;
456
+ $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
457
+ that._clear(event);
458
+ });
459
+ } else {
460
+ this._clear(event, noPropagation);
461
+ }
462
+
463
+ return false;
464
+
465
+ },
466
+
467
+ cancel: function() {
468
+
469
+ if(this.dragging) {
470
+
471
+ this._mouseUp({ target: null });
472
+
473
+ if(this.options.helper === "original") {
474
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
475
+ } else {
476
+ this.currentItem.show();
477
+ }
478
+
479
+ //Post deactivating events to containers
480
+ for (var i = this.containers.length - 1; i >= 0; i--){
481
+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
482
+ if(this.containers[i].containerCache.over) {
483
+ this.containers[i]._trigger("out", null, this._uiHash(this));
484
+ this.containers[i].containerCache.over = 0;
485
+ }
486
+ }
487
+
488
+ }
489
+
490
+ if (this.placeholder) {
491
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
492
+ if(this.placeholder[0].parentNode) {
493
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
494
+ }
495
+ if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
496
+ this.helper.remove();
497
+ }
498
+
499
+ $.extend(this, {
500
+ helper: null,
501
+ dragging: false,
502
+ reverting: false,
503
+ _noFinalSort: null
504
+ });
505
+
506
+ if(this.domPosition.prev) {
507
+ $(this.domPosition.prev).after(this.currentItem);
508
+ } else {
509
+ $(this.domPosition.parent).prepend(this.currentItem);
510
+ }
511
+ }
512
+
513
+ return this;
514
+
515
+ },
516
+
517
+ serialize: function(o) {
518
+
519
+ var items = this._getItemsAsjQuery(o && o.connected),
520
+ str = [];
521
+ o = o || {};
522
+
523
+ $(items).each(function() {
524
+ var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
525
+ if (res) {
526
+ str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
527
+ }
528
+ });
529
+
530
+ if(!str.length && o.key) {
531
+ str.push(o.key + "=");
532
+ }
533
+
534
+ return str.join("&");
535
+
536
+ },
537
+
538
+ toArray: function(o) {
539
+
540
+ var items = this._getItemsAsjQuery(o && o.connected),
541
+ ret = [];
542
+
543
+ o = o || {};
544
+
545
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
546
+ return ret;
547
+
548
+ },
549
+
550
+ /* Be careful with the following core functions */
551
+ _intersectsWith: function(item) {
552
+
553
+ var x1 = this.positionAbs.left,
554
+ x2 = x1 + this.helperProportions.width,
555
+ y1 = this.positionAbs.top,
556
+ y2 = y1 + this.helperProportions.height,
557
+ l = item.left,
558
+ r = l + item.width,
559
+ t = item.top,
560
+ b = t + item.height,
561
+ dyClick = this.offset.click.top,
562
+ dxClick = this.offset.click.left,
563
+ isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
564
+ isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
565
+ isOverElement = isOverElementHeight && isOverElementWidth;
566
+
567
+ if ( this.options.tolerance === "pointer" ||
568
+ this.options.forcePointerForContainers ||
569
+ (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
570
+ ) {
571
+ return isOverElement;
572
+ } else {
573
+
574
+ return (l < x1 + (this.helperProportions.width / 2) && // Right Half
575
+ x2 - (this.helperProportions.width / 2) < r && // Left Half
576
+ t < y1 + (this.helperProportions.height / 2) && // Bottom Half
577
+ y2 - (this.helperProportions.height / 2) < b ); // Top Half
578
+
579
+ }
580
+ },
581
+
582
+ _intersectsWithPointer: function(item) {
583
+
584
+ var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
585
+ isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
586
+ isOverElement = isOverElementHeight && isOverElementWidth,
587
+ verticalDirection = this._getDragVerticalDirection(),
588
+ horizontalDirection = this._getDragHorizontalDirection();
589
+
590
+ if (!isOverElement) {
591
+ return false;
592
+ }
593
+
594
+ return this.floating ?
595
+ ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
596
+ : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
597
+
598
+ },
599
+
600
+ _intersectsWithSides: function(item) {
601
+
602
+ var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
603
+ isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
604
+ verticalDirection = this._getDragVerticalDirection(),
605
+ horizontalDirection = this._getDragHorizontalDirection();
606
+
607
+ if (this.floating && horizontalDirection) {
608
+ return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
609
+ } else {
610
+ return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
611
+ }
612
+
613
+ },
614
+
615
+ _getDragVerticalDirection: function() {
616
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
617
+ return delta !== 0 && (delta > 0 ? "down" : "up");
618
+ },
619
+
620
+ _getDragHorizontalDirection: function() {
621
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
622
+ return delta !== 0 && (delta > 0 ? "right" : "left");
623
+ },
624
+
625
+ refresh: function(event) {
626
+ this._refreshItems(event);
627
+ this._setHandleClassName();
628
+ this.refreshPositions();
629
+ return this;
630
+ },
631
+
632
+ _connectWith: function() {
633
+ var options = this.options;
634
+ return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
635
+ },
636
+
637
+ _getItemsAsjQuery: function(connected) {
638
+
639
+ var i, j, cur, inst,
640
+ items = [],
641
+ queries = [],
642
+ connectWith = this._connectWith();
643
+
644
+ if(connectWith && connected) {
645
+ for (i = connectWith.length - 1; i >= 0; i--){
646
+ cur = $(connectWith[i], this.document[0]);
647
+ for ( j = cur.length - 1; j >= 0; j--){
648
+ inst = $.data(cur[j], this.widgetFullName);
649
+ if(inst && inst !== this && !inst.options.disabled) {
650
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
651
+ }
652
+ }
653
+ }
654
+ }
655
+
656
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
657
+
658
+ function addItems() {
659
+ items.push( this );
660
+ }
661
+ for (i = queries.length - 1; i >= 0; i--){
662
+ queries[i][0].each( addItems );
663
+ }
664
+
665
+ return $(items);
666
+
667
+ },
668
+
669
+ _removeCurrentsFromItems: function() {
670
+
671
+ var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
672
+
673
+ this.items = $.grep(this.items, function (item) {
674
+ for (var j=0; j < list.length; j++) {
675
+ if(list[j] === item.item[0]) {
676
+ return false;
677
+ }
678
+ }
679
+ return true;
680
+ });
681
+
682
+ },
683
+
684
+ _refreshItems: function(event) {
685
+
686
+ this.items = [];
687
+ this.containers = [this];
688
+
689
+ var i, j, cur, inst, targetData, _queries, item, queriesLength,
690
+ items = this.items,
691
+ queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
692
+ connectWith = this._connectWith();
693
+
694
+ if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
695
+ for (i = connectWith.length - 1; i >= 0; i--){
696
+ cur = $(connectWith[i], this.document[0]);
697
+ for (j = cur.length - 1; j >= 0; j--){
698
+ inst = $.data(cur[j], this.widgetFullName);
699
+ if(inst && inst !== this && !inst.options.disabled) {
700
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
701
+ this.containers.push(inst);
702
+ }
703
+ }
704
+ }
705
+ }
706
+
707
+ for (i = queries.length - 1; i >= 0; i--) {
708
+ targetData = queries[i][1];
709
+ _queries = queries[i][0];
710
+
711
+ for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
712
+ item = $(_queries[j]);
713
+
714
+ item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
715
+
716
+ items.push({
717
+ item: item,
718
+ instance: targetData,
719
+ width: 0, height: 0,
720
+ left: 0, top: 0
721
+ });
722
+ }
723
+ }
724
+
725
+ },
726
+
727
+ refreshPositions: function(fast) {
728
+
729
+ // Determine whether items are being displayed horizontally
730
+ this.floating = this.items.length ?
731
+ this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
732
+ false;
733
+
734
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
735
+ if(this.offsetParent && this.helper) {
736
+ this.offset.parent = this._getParentOffset();
737
+ }
738
+
739
+ var i, item, t, p;
740
+
741
+ for (i = this.items.length - 1; i >= 0; i--){
742
+ item = this.items[i];
743
+
744
+ //We ignore calculating positions of all connected containers when we're not over them
745
+ if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
746
+ continue;
747
+ }
748
+
749
+ t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
750
+
751
+ if (!fast) {
752
+ item.width = t.outerWidth();
753
+ item.height = t.outerHeight();
754
+ }
755
+
756
+ p = t.offset();
757
+ item.left = p.left;
758
+ item.top = p.top;
759
+ }
760
+
761
+ if(this.options.custom && this.options.custom.refreshContainers) {
762
+ this.options.custom.refreshContainers.call(this);
763
+ } else {
764
+ for (i = this.containers.length - 1; i >= 0; i--){
765
+ p = this.containers[i].element.offset();
766
+ this.containers[i].containerCache.left = p.left;
767
+ this.containers[i].containerCache.top = p.top;
768
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
769
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
770
+ }
771
+ }
772
+
773
+ return this;
774
+ },
775
+
776
+ _createPlaceholder: function(that) {
777
+ that = that || this;
778
+ var className,
779
+ o = that.options;
780
+
781
+ if(!o.placeholder || o.placeholder.constructor === String) {
782
+ className = o.placeholder;
783
+ o.placeholder = {
784
+ element: function() {
785
+
786
+ var nodeName = that.currentItem[0].nodeName.toLowerCase(),
787
+ element = $( "<" + nodeName + ">", that.document[0] )
788
+ .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
789
+ .removeClass("ui-sortable-helper");
790
+
791
+ if ( nodeName === "tbody" ) {
792
+ that._createTrPlaceholder(
793
+ that.currentItem.find( "tr" ).eq( 0 ),
794
+ $( "<tr>", that.document[ 0 ] ).appendTo( element )
795
+ );
796
+ } else if ( nodeName === "tr" ) {
797
+ that._createTrPlaceholder( that.currentItem, element );
798
+ } else if ( nodeName === "img" ) {
799
+ element.attr( "src", that.currentItem.attr( "src" ) );
800
+ }
801
+
802
+ if ( !className ) {
803
+ element.css( "visibility", "hidden" );
804
+ }
805
+
806
+ return element;
807
+ },
808
+ update: function(container, p) {
809
+
810
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
811
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
812
+ if(className && !o.forcePlaceholderSize) {
813
+ return;
814
+ }
815
+
816
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
817
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
818
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
819
+ }
820
+ };
821
+ }
822
+
823
+ //Create the placeholder
824
+ that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
825
+
826
+ //Append it after the actual current item
827
+ that.currentItem.after(that.placeholder);
828
+
829
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
830
+ o.placeholder.update(that, that.placeholder);
831
+
832
+ },
833
+
834
+ _createTrPlaceholder: function( sourceTr, targetTr ) {
835
+ var that = this;
836
+
837
+ sourceTr.children().each(function() {
838
+ $( "<td>&#160;</td>", that.document[ 0 ] )
839
+ .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
840
+ .appendTo( targetTr );
841
+ });
842
+ },
843
+
844
+ _contactContainers: function(event) {
845
+ var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
846
+ innermostContainer = null,
847
+ innermostIndex = null;
848
+
849
+ // get innermost container that intersects with item
850
+ for (i = this.containers.length - 1; i >= 0; i--) {
851
+
852
+ // never consider a container that's located within the item itself
853
+ if($.contains(this.currentItem[0], this.containers[i].element[0])) {
854
+ continue;
855
+ }
856
+
857
+ if(this._intersectsWith(this.containers[i].containerCache)) {
858
+
859
+ // if we've already found a container and it's more "inner" than this, then continue
860
+ if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
861
+ continue;
862
+ }
863
+
864
+ innermostContainer = this.containers[i];
865
+ innermostIndex = i;
866
+
867
+ } else {
868
+ // container doesn't intersect. trigger "out" event if necessary
869
+ if(this.containers[i].containerCache.over) {
870
+ this.containers[i]._trigger("out", event, this._uiHash(this));
871
+ this.containers[i].containerCache.over = 0;
872
+ }
873
+ }
874
+
875
+ }
876
+
877
+ // if no intersecting containers found, return
878
+ if(!innermostContainer) {
879
+ return;
880
+ }
881
+
882
+ // move the item into the container if it's not there already
883
+ if(this.containers.length === 1) {
884
+ if (!this.containers[innermostIndex].containerCache.over) {
885
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
886
+ this.containers[innermostIndex].containerCache.over = 1;
887
+ }
888
+ } else {
889
+
890
+ //When entering a new container, we will find the item with the least distance and append our item near it
891
+ dist = 10000;
892
+ itemWithLeastDistance = null;
893
+ floating = innermostContainer.floating || this._isFloating(this.currentItem);
894
+ posProperty = floating ? "left" : "top";
895
+ sizeProperty = floating ? "width" : "height";
896
+ axis = floating ? "clientX" : "clientY";
897
+
898
+ for (j = this.items.length - 1; j >= 0; j--) {
899
+ if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
900
+ continue;
901
+ }
902
+ if(this.items[j].item[0] === this.currentItem[0]) {
903
+ continue;
904
+ }
905
+
906
+ cur = this.items[j].item.offset()[posProperty];
907
+ nearBottom = false;
908
+ if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
909
+ nearBottom = true;
910
+ }
911
+
912
+ if ( Math.abs( event[ axis ] - cur ) < dist ) {
913
+ dist = Math.abs( event[ axis ] - cur );
914
+ itemWithLeastDistance = this.items[ j ];
915
+ this.direction = nearBottom ? "up": "down";
916
+ }
917
+ }
918
+
919
+ //Check if dropOnEmpty is enabled
920
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
921
+ return;
922
+ }
923
+
924
+ if(this.currentContainer === this.containers[innermostIndex]) {
925
+ if ( !this.currentContainer.containerCache.over ) {
926
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
927
+ this.currentContainer.containerCache.over = 1;
928
+ }
929
+ return;
930
+ }
931
+
932
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
933
+ this._trigger("change", event, this._uiHash());
934
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
935
+ this.currentContainer = this.containers[innermostIndex];
936
+
937
+ //Update the placeholder
938
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
939
+
940
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
941
+ this.containers[innermostIndex].containerCache.over = 1;
942
+ }
943
+
944
+
945
+ },
946
+
947
+ _createHelper: function(event) {
948
+
949
+ var o = this.options,
950
+ helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
951
+
952
+ //Add the helper to the DOM if that didn't happen already
953
+ if(!helper.parents("body").length) {
954
+ $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
955
+ }
956
+
957
+ if(helper[0] === this.currentItem[0]) {
958
+ this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
959
+ }
960
+
961
+ if(!helper[0].style.width || o.forceHelperSize) {
962
+ helper.width(this.currentItem.width());
963
+ }
964
+ if(!helper[0].style.height || o.forceHelperSize) {
965
+ helper.height(this.currentItem.height());
966
+ }
967
+
968
+ return helper;
969
+
970
+ },
971
+
972
+ _adjustOffsetFromHelper: function(obj) {
973
+ if (typeof obj === "string") {
974
+ obj = obj.split(" ");
975
+ }
976
+ if ($.isArray(obj)) {
977
+ obj = {left: +obj[0], top: +obj[1] || 0};
978
+ }
979
+ if ("left" in obj) {
980
+ this.offset.click.left = obj.left + this.margins.left;
981
+ }
982
+ if ("right" in obj) {
983
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
984
+ }
985
+ if ("top" in obj) {
986
+ this.offset.click.top = obj.top + this.margins.top;
987
+ }
988
+ if ("bottom" in obj) {
989
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
990
+ }
991
+ },
992
+
993
+ _getParentOffset: function() {
994
+
995
+
996
+ //Get the offsetParent and cache its position
997
+ this.offsetParent = this.helper.offsetParent();
998
+ var po = this.offsetParent.offset();
999
+
1000
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
1001
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1002
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1003
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1004
+ if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1005
+ po.left += this.scrollParent.scrollLeft();
1006
+ po.top += this.scrollParent.scrollTop();
1007
+ }
1008
+
1009
+ // This needs to be actually done for all browsers, since pageX/pageY includes this information
1010
+ // with an ugly IE fix
1011
+ if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1012
+ po = { top: 0, left: 0 };
1013
+ }
1014
+
1015
+ return {
1016
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1017
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1018
+ };
1019
+
1020
+ },
1021
+
1022
+ _getRelativeOffset: function() {
1023
+
1024
+ if(this.cssPosition === "relative") {
1025
+ var p = this.currentItem.position();
1026
+ return {
1027
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1028
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1029
+ };
1030
+ } else {
1031
+ return { top: 0, left: 0 };
1032
+ }
1033
+
1034
+ },
1035
+
1036
+ _cacheMargins: function() {
1037
+ this.margins = {
1038
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
1039
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
1040
+ };
1041
+ },
1042
+
1043
+ _cacheHelperProportions: function() {
1044
+ this.helperProportions = {
1045
+ width: this.helper.outerWidth(),
1046
+ height: this.helper.outerHeight()
1047
+ };
1048
+ },
1049
+
1050
+ _setContainment: function() {
1051
+
1052
+ var ce, co, over,
1053
+ o = this.options;
1054
+ if(o.containment === "parent") {
1055
+ o.containment = this.helper[0].parentNode;
1056
+ }
1057
+ if(o.containment === "document" || o.containment === "window") {
1058
+ this.containment = [
1059
+ 0 - this.offset.relative.left - this.offset.parent.left,
1060
+ 0 - this.offset.relative.top - this.offset.parent.top,
1061
+ o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
1062
+ (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1063
+ ];
1064
+ }
1065
+
1066
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
1067
+ ce = $(o.containment)[0];
1068
+ co = $(o.containment).offset();
1069
+ over = ($(ce).css("overflow") !== "hidden");
1070
+
1071
+ this.containment = [
1072
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
1073
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
1074
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
1075
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
1076
+ ];
1077
+ }
1078
+
1079
+ },
1080
+
1081
+ _convertPositionTo: function(d, pos) {
1082
+
1083
+ if(!pos) {
1084
+ pos = this.position;
1085
+ }
1086
+ var mod = d === "absolute" ? 1 : -1,
1087
+ scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1088
+ scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1089
+
1090
+ return {
1091
+ top: (
1092
+ pos.top + // The absolute mouse position
1093
+ this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1094
+ this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1095
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1096
+ ),
1097
+ left: (
1098
+ pos.left + // The absolute mouse position
1099
+ this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1100
+ this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
1101
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1102
+ )
1103
+ };
1104
+
1105
+ },
1106
+
1107
+ _generatePosition: function(event) {
1108
+
1109
+ var top, left,
1110
+ o = this.options,
1111
+ pageX = event.pageX,
1112
+ pageY = event.pageY,
1113
+ scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1114
+
1115
+ // This is another very weird special case that only happens for relative elements:
1116
+ // 1. If the css position is relative
1117
+ // 2. and the scroll parent is the document or similar to the offset parent
1118
+ // we have to refresh the relative offset during the scroll so there are no jumps
1119
+ if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
1120
+ this.offset.relative = this._getRelativeOffset();
1121
+ }
1122
+
1123
+ /*
1124
+ * - Position constraining -
1125
+ * Constrain the position to a mix of grid, containment.
1126
+ */
1127
+
1128
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1129
+
1130
+ if(this.containment) {
1131
+ if(event.pageX - this.offset.click.left < this.containment[0]) {
1132
+ pageX = this.containment[0] + this.offset.click.left;
1133
+ }
1134
+ if(event.pageY - this.offset.click.top < this.containment[1]) {
1135
+ pageY = this.containment[1] + this.offset.click.top;
1136
+ }
1137
+ if(event.pageX - this.offset.click.left > this.containment[2]) {
1138
+ pageX = this.containment[2] + this.offset.click.left;
1139
+ }
1140
+ if(event.pageY - this.offset.click.top > this.containment[3]) {
1141
+ pageY = this.containment[3] + this.offset.click.top;
1142
+ }
1143
+ }
1144
+
1145
+ if(o.grid) {
1146
+ top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
1147
+ pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1148
+
1149
+ left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
1150
+ pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1151
+ }
1152
+
1153
+ }
1154
+
1155
+ return {
1156
+ top: (
1157
+ pageY - // The absolute mouse position
1158
+ this.offset.click.top - // Click offset (relative to the element)
1159
+ this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
1160
+ this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
1161
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1162
+ ),
1163
+ left: (
1164
+ pageX - // The absolute mouse position
1165
+ this.offset.click.left - // Click offset (relative to the element)
1166
+ this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
1167
+ this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
1168
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1169
+ )
1170
+ };
1171
+
1172
+ },
1173
+
1174
+ _rearrange: function(event, i, a, hardRefresh) {
1175
+
1176
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
1177
+
1178
+ //Various things done here to improve the performance:
1179
+ // 1. we create a setTimeout, that calls refreshPositions
1180
+ // 2. on the instance, we have a counter variable, that get's higher after every append
1181
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
1182
+ // 4. this lets only the last addition to the timeout stack through
1183
+ this.counter = this.counter ? ++this.counter : 1;
1184
+ var counter = this.counter;
1185
+
1186
+ this._delay(function() {
1187
+ if(counter === this.counter) {
1188
+ this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
1189
+ }
1190
+ });
1191
+
1192
+ },
1193
+
1194
+ _clear: function(event, noPropagation) {
1195
+
1196
+ this.reverting = false;
1197
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
1198
+ // everything else normalized again
1199
+ var i,
1200
+ delayedTriggers = [];
1201
+
1202
+ // We first have to update the dom position of the actual currentItem
1203
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
1204
+ if(!this._noFinalSort && this.currentItem.parent().length) {
1205
+ this.placeholder.before(this.currentItem);
1206
+ }
1207
+ this._noFinalSort = null;
1208
+
1209
+ if(this.helper[0] === this.currentItem[0]) {
1210
+ for(i in this._storedCSS) {
1211
+ if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
1212
+ this._storedCSS[i] = "";
1213
+ }
1214
+ }
1215
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1216
+ } else {
1217
+ this.currentItem.show();
1218
+ }
1219
+
1220
+ if(this.fromOutside && !noPropagation) {
1221
+ delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
1222
+ }
1223
+ if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
1224
+ delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
1225
+ }
1226
+
1227
+ // Check if the items Container has Changed and trigger appropriate
1228
+ // events.
1229
+ if (this !== this.currentContainer) {
1230
+ if(!noPropagation) {
1231
+ delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
1232
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
1233
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
1234
+ }
1235
+ }
1236
+
1237
+
1238
+ //Post events to containers
1239
+ function delayEvent( type, instance, container ) {
1240
+ return function( event ) {
1241
+ container._trigger( type, event, instance._uiHash( instance ) );
1242
+ };
1243
+ }
1244
+ for (i = this.containers.length - 1; i >= 0; i--){
1245
+ if (!noPropagation) {
1246
+ delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
1247
+ }
1248
+ if(this.containers[i].containerCache.over) {
1249
+ delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
1250
+ this.containers[i].containerCache.over = 0;
1251
+ }
1252
+ }
1253
+
1254
+ //Do what was originally in plugins
1255
+ if ( this.storedCursor ) {
1256
+ this.document.find( "body" ).css( "cursor", this.storedCursor );
1257
+ this.storedStylesheet.remove();
1258
+ }
1259
+ if(this._storedOpacity) {
1260
+ this.helper.css("opacity", this._storedOpacity);
1261
+ }
1262
+ if(this._storedZIndex) {
1263
+ this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
1264
+ }
1265
+
1266
+ this.dragging = false;
1267
+
1268
+ if(!noPropagation) {
1269
+ this._trigger("beforeStop", event, this._uiHash());
1270
+ }
1271
+
1272
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1273
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1274
+
1275
+ if ( !this.cancelHelperRemoval ) {
1276
+ if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
1277
+ this.helper.remove();
1278
+ }
1279
+ this.helper = null;
1280
+ }
1281
+
1282
+ if(!noPropagation) {
1283
+ for (i=0; i < delayedTriggers.length; i++) {
1284
+ delayedTriggers[i].call(this, event);
1285
+ } //Trigger all delayed events
1286
+ this._trigger("stop", event, this._uiHash());
1287
+ }
1288
+
1289
+ this.fromOutside = false;
1290
+ return !this.cancelHelperRemoval;
1291
+
1292
+ },
1293
+
1294
+ _trigger: function() {
1295
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
1296
+ this.cancel();
1297
+ }
1298
+ },
1299
+
1300
+ _uiHash: function(_inst) {
1301
+ var inst = _inst || this;
1302
+ return {
1303
+ helper: inst.helper,
1304
+ placeholder: inst.placeholder || $([]),
1305
+ position: inst.position,
1306
+ originalPosition: inst.originalPosition,
1307
+ offset: inst.positionAbs,
1308
+ item: inst.currentItem,
1309
+ sender: _inst ? _inst.element : null
1310
+ };
1311
+ }
1312
+
1313
+ });
1314
+
1315
+ }));