alchemy_cms 7.0.5 → 7.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -0
  3. data/CHANGELOG.md +6 -0
  4. data/Gemfile +6 -1
  5. data/alchemy_cms.gemspec +2 -3
  6. data/app/assets/javascripts/alchemy/admin.js +0 -1
  7. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -1
  8. data/app/controllers/alchemy/admin/ingredients_controller.rb +2 -1
  9. data/app/models/alchemy/page/publisher.rb +14 -12
  10. data/app/models/alchemy/page_mutex.rb +31 -0
  11. data/app/models/alchemy/picture/url.rb +9 -1
  12. data/db/migrate/20231113104432_create_page_mutexes.rb +8 -0
  13. data/lib/alchemy/version.rb +1 -1
  14. data/lib/alchemy_cms.rb +0 -1
  15. data/vendor/assets/javascripts/jquery-ui/data.js +45 -0
  16. data/vendor/assets/javascripts/jquery-ui/ie.js +20 -0
  17. data/vendor/assets/javascripts/jquery-ui/keycode.js +51 -0
  18. data/vendor/assets/javascripts/jquery-ui/plugin.js +49 -0
  19. data/vendor/assets/javascripts/jquery-ui/safe-active-element.js +46 -0
  20. data/vendor/assets/javascripts/jquery-ui/safe-blur.js +27 -0
  21. data/vendor/assets/javascripts/jquery-ui/scroll-parent.js +50 -0
  22. data/vendor/assets/javascripts/jquery-ui/unique-id.js +54 -0
  23. data/vendor/assets/javascripts/jquery-ui/version.js +20 -0
  24. data/vendor/assets/javascripts/jquery-ui/widget.js +754 -0
  25. data/vendor/assets/javascripts/jquery-ui/widgets/draggable.js +1268 -0
  26. data/vendor/assets/javascripts/jquery-ui/widgets/mouse.js +241 -0
  27. data/vendor/assets/javascripts/jquery-ui/widgets/sortable.js +1623 -0
  28. data/vendor/assets/javascripts/jquery-ui/widgets/tabs.js +931 -0
  29. metadata +36 -34
@@ -0,0 +1,1268 @@
1
+ //= require jquery-ui/widgets/mouse
2
+ //= require jquery-ui/data
3
+ //= require jquery-ui/plugin
4
+ //= require jquery-ui/safe-active-element
5
+ //= require jquery-ui/safe-blur
6
+ //= require jquery-ui/scroll-parent
7
+ //= require jquery-ui/version
8
+ //= require jquery-ui/widget
9
+
10
+ /*!
11
+ * jQuery UI Draggable 1.13.0
12
+ * http://jqueryui.com
13
+ *
14
+ * Copyright jQuery Foundation and other contributors
15
+ * Released under the MIT license.
16
+ * http://jquery.org/license
17
+ */
18
+
19
+ //>>label: Draggable
20
+ //>>group: Interactions
21
+ //>>description: Enables dragging functionality for any element.
22
+ //>>docs: http://api.jqueryui.com/draggable/
23
+ //>>demos: http://jqueryui.com/draggable/
24
+ //>>css.structure: ../../themes/base/draggable.css
25
+
26
+ ( function( factory ) {
27
+ "use strict";
28
+
29
+ if ( typeof define === "function" && define.amd ) {
30
+
31
+ // AMD. Register as an anonymous module.
32
+ define( [
33
+ "jquery",
34
+ "./mouse",
35
+ "../data",
36
+ "../plugin",
37
+ "../safe-active-element",
38
+ "../safe-blur",
39
+ "../scroll-parent",
40
+ "../version",
41
+ "../widget"
42
+ ], factory );
43
+ } else {
44
+
45
+ // Browser globals
46
+ factory( jQuery );
47
+ }
48
+ } )( function( $ ) {
49
+ "use strict";
50
+
51
+ $.widget( "ui.draggable", $.ui.mouse, {
52
+ version: "1.13.0",
53
+ widgetEventPrefix: "drag",
54
+ options: {
55
+ addClasses: true,
56
+ appendTo: "parent",
57
+ axis: false,
58
+ connectToSortable: false,
59
+ containment: false,
60
+ cursor: "auto",
61
+ cursorAt: false,
62
+ grid: false,
63
+ handle: false,
64
+ helper: "original",
65
+ iframeFix: false,
66
+ opacity: false,
67
+ refreshPositions: false,
68
+ revert: false,
69
+ revertDuration: 500,
70
+ scope: "default",
71
+ scroll: true,
72
+ scrollSensitivity: 20,
73
+ scrollSpeed: 20,
74
+ snap: false,
75
+ snapMode: "both",
76
+ snapTolerance: 20,
77
+ stack: false,
78
+ zIndex: false,
79
+
80
+ // Callbacks
81
+ drag: null,
82
+ start: null,
83
+ stop: null
84
+ },
85
+ _create: function() {
86
+
87
+ if ( this.options.helper === "original" ) {
88
+ this._setPositionRelative();
89
+ }
90
+ if ( this.options.addClasses ) {
91
+ this._addClass( "ui-draggable" );
92
+ }
93
+ this._setHandleClassName();
94
+
95
+ this._mouseInit();
96
+ },
97
+
98
+ _setOption: function( key, value ) {
99
+ this._super( key, value );
100
+ if ( key === "handle" ) {
101
+ this._removeHandleClassName();
102
+ this._setHandleClassName();
103
+ }
104
+ },
105
+
106
+ _destroy: function() {
107
+ if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
108
+ this.destroyOnClear = true;
109
+ return;
110
+ }
111
+ this._removeHandleClassName();
112
+ this._mouseDestroy();
113
+ },
114
+
115
+ _mouseCapture: function( event ) {
116
+ var o = this.options;
117
+
118
+ // Among others, prevent a drag on a resizable-handle
119
+ if ( this.helper || o.disabled ||
120
+ $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
121
+ return false;
122
+ }
123
+
124
+ //Quit if we're not on a valid handle
125
+ this.handle = this._getHandle( event );
126
+ if ( !this.handle ) {
127
+ return false;
128
+ }
129
+
130
+ this._blurActiveElement( event );
131
+
132
+ this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
133
+
134
+ return true;
135
+
136
+ },
137
+
138
+ _blockFrames: function( selector ) {
139
+ this.iframeBlocks = this.document.find( selector ).map( function() {
140
+ var iframe = $( this );
141
+
142
+ return $( "<div>" )
143
+ .css( "position", "absolute" )
144
+ .appendTo( iframe.parent() )
145
+ .outerWidth( iframe.outerWidth() )
146
+ .outerHeight( iframe.outerHeight() )
147
+ .offset( iframe.offset() )[ 0 ];
148
+ } );
149
+ },
150
+
151
+ _unblockFrames: function() {
152
+ if ( this.iframeBlocks ) {
153
+ this.iframeBlocks.remove();
154
+ delete this.iframeBlocks;
155
+ }
156
+ },
157
+
158
+ _blurActiveElement: function( event ) {
159
+ var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
160
+ target = $( event.target );
161
+
162
+ // Don't blur if the event occurred on an element that is within
163
+ // the currently focused element
164
+ // See #10527, #12472
165
+ if ( target.closest( activeElement ).length ) {
166
+ return;
167
+ }
168
+
169
+ // Blur any element that currently has focus, see #4261
170
+ $.ui.safeBlur( activeElement );
171
+ },
172
+
173
+ _mouseStart: function( event ) {
174
+
175
+ var o = this.options;
176
+
177
+ //Create and append the visible helper
178
+ this.helper = this._createHelper( event );
179
+
180
+ this._addClass( this.helper, "ui-draggable-dragging" );
181
+
182
+ //Cache the helper size
183
+ this._cacheHelperProportions();
184
+
185
+ //If ddmanager is used for droppables, set the global draggable
186
+ if ( $.ui.ddmanager ) {
187
+ $.ui.ddmanager.current = this;
188
+ }
189
+
190
+ /*
191
+ * - Position generation -
192
+ * This block generates everything position related - it's the core of draggables.
193
+ */
194
+
195
+ //Cache the margins of the original element
196
+ this._cacheMargins();
197
+
198
+ //Store the helper's css position
199
+ this.cssPosition = this.helper.css( "position" );
200
+ this.scrollParent = this.helper.scrollParent( true );
201
+ this.offsetParent = this.helper.offsetParent();
202
+ this.hasFixedAncestor = this.helper.parents().filter( function() {
203
+ return $( this ).css( "position" ) === "fixed";
204
+ } ).length > 0;
205
+
206
+ //The element's absolute position on the page minus margins
207
+ this.positionAbs = this.element.offset();
208
+ this._refreshOffsets( event );
209
+
210
+ //Generate the original position
211
+ this.originalPosition = this.position = this._generatePosition( event, false );
212
+ this.originalPageX = event.pageX;
213
+ this.originalPageY = event.pageY;
214
+
215
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
216
+ if ( o.cursorAt ) {
217
+ this._adjustOffsetFromHelper( o.cursorAt );
218
+ }
219
+
220
+ //Set a containment if given in the options
221
+ this._setContainment();
222
+
223
+ //Trigger event + callbacks
224
+ if ( this._trigger( "start", event ) === false ) {
225
+ this._clear();
226
+ return false;
227
+ }
228
+
229
+ //Recache the helper size
230
+ this._cacheHelperProportions();
231
+
232
+ //Prepare the droppable offsets
233
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
234
+ $.ui.ddmanager.prepareOffsets( this, event );
235
+ }
236
+
237
+ // Execute the drag once - this causes the helper not to be visible before getting its
238
+ // correct position
239
+ this._mouseDrag( event, true );
240
+
241
+ // If the ddmanager is used for droppables, inform the manager that dragging has started
242
+ // (see #5003)
243
+ if ( $.ui.ddmanager ) {
244
+ $.ui.ddmanager.dragStart( this, event );
245
+ }
246
+
247
+ return true;
248
+ },
249
+
250
+ _refreshOffsets: function( event ) {
251
+ this.offset = {
252
+ top: this.positionAbs.top - this.margins.top,
253
+ left: this.positionAbs.left - this.margins.left,
254
+ scroll: false,
255
+ parent: this._getParentOffset(),
256
+ relative: this._getRelativeOffset()
257
+ };
258
+
259
+ this.offset.click = {
260
+ left: event.pageX - this.offset.left,
261
+ top: event.pageY - this.offset.top
262
+ };
263
+ },
264
+
265
+ _mouseDrag: function( event, noPropagation ) {
266
+
267
+ // reset any necessary cached properties (see #5009)
268
+ if ( this.hasFixedAncestor ) {
269
+ this.offset.parent = this._getParentOffset();
270
+ }
271
+
272
+ //Compute the helpers position
273
+ this.position = this._generatePosition( event, true );
274
+ this.positionAbs = this._convertPositionTo( "absolute" );
275
+
276
+ //Call plugins and callbacks and use the resulting position if something is returned
277
+ if ( !noPropagation ) {
278
+ var ui = this._uiHash();
279
+ if ( this._trigger( "drag", event, ui ) === false ) {
280
+ this._mouseUp( new $.Event( "mouseup", event ) );
281
+ return false;
282
+ }
283
+ this.position = ui.position;
284
+ }
285
+
286
+ this.helper[ 0 ].style.left = this.position.left + "px";
287
+ this.helper[ 0 ].style.top = this.position.top + "px";
288
+
289
+ if ( $.ui.ddmanager ) {
290
+ $.ui.ddmanager.drag( this, event );
291
+ }
292
+
293
+ return false;
294
+ },
295
+
296
+ _mouseStop: function( event ) {
297
+
298
+ //If we are using droppables, inform the manager about the drop
299
+ var that = this,
300
+ dropped = false;
301
+ if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
302
+ dropped = $.ui.ddmanager.drop( this, event );
303
+ }
304
+
305
+ //if a drop comes from outside (a sortable)
306
+ if ( this.dropped ) {
307
+ dropped = this.dropped;
308
+ this.dropped = false;
309
+ }
310
+
311
+ if ( ( this.options.revert === "invalid" && !dropped ) ||
312
+ ( this.options.revert === "valid" && dropped ) ||
313
+ this.options.revert === true || ( typeof this.options.revert === "function" &&
314
+ this.options.revert.call( this.element, dropped ) )
315
+ ) {
316
+ $( this.helper ).animate(
317
+ this.originalPosition,
318
+ parseInt( this.options.revertDuration, 10 ),
319
+ function() {
320
+ if ( that._trigger( "stop", event ) !== false ) {
321
+ that._clear();
322
+ }
323
+ }
324
+ );
325
+ } else {
326
+ if ( this._trigger( "stop", event ) !== false ) {
327
+ this._clear();
328
+ }
329
+ }
330
+
331
+ return false;
332
+ },
333
+
334
+ _mouseUp: function( event ) {
335
+ this._unblockFrames();
336
+
337
+ // If the ddmanager is used for droppables, inform the manager that dragging has stopped
338
+ // (see #5003)
339
+ if ( $.ui.ddmanager ) {
340
+ $.ui.ddmanager.dragStop( this, event );
341
+ }
342
+
343
+ // Only need to focus if the event occurred on the draggable itself, see #10527
344
+ if ( this.handleElement.is( event.target ) ) {
345
+
346
+ // The interaction is over; whether or not the click resulted in a drag,
347
+ // focus the element
348
+ this.element.trigger( "focus" );
349
+ }
350
+
351
+ return $.ui.mouse.prototype._mouseUp.call( this, event );
352
+ },
353
+
354
+ cancel: function() {
355
+
356
+ if ( this.helper.is( ".ui-draggable-dragging" ) ) {
357
+ this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
358
+ } else {
359
+ this._clear();
360
+ }
361
+
362
+ return this;
363
+
364
+ },
365
+
366
+ _getHandle: function( event ) {
367
+ return this.options.handle ?
368
+ !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
369
+ true;
370
+ },
371
+
372
+ _setHandleClassName: function() {
373
+ this.handleElement = this.options.handle ?
374
+ this.element.find( this.options.handle ) : this.element;
375
+ this._addClass( this.handleElement, "ui-draggable-handle" );
376
+ },
377
+
378
+ _removeHandleClassName: function() {
379
+ this._removeClass( this.handleElement, "ui-draggable-handle" );
380
+ },
381
+
382
+ _createHelper: function( event ) {
383
+
384
+ var o = this.options,
385
+ helperIsFunction = typeof o.helper === "function",
386
+ helper = helperIsFunction ?
387
+ $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
388
+ ( o.helper === "clone" ?
389
+ this.element.clone().removeAttr( "id" ) :
390
+ this.element );
391
+
392
+ if ( !helper.parents( "body" ).length ) {
393
+ helper.appendTo( ( o.appendTo === "parent" ?
394
+ this.element[ 0 ].parentNode :
395
+ o.appendTo ) );
396
+ }
397
+
398
+ // Http://bugs.jqueryui.com/ticket/9446
399
+ // a helper function can return the original element
400
+ // which wouldn't have been set to relative in _create
401
+ if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
402
+ this._setPositionRelative();
403
+ }
404
+
405
+ if ( helper[ 0 ] !== this.element[ 0 ] &&
406
+ !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
407
+ helper.css( "position", "absolute" );
408
+ }
409
+
410
+ return helper;
411
+
412
+ },
413
+
414
+ _setPositionRelative: function() {
415
+ if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
416
+ this.element[ 0 ].style.position = "relative";
417
+ }
418
+ },
419
+
420
+ _adjustOffsetFromHelper: function( obj ) {
421
+ if ( typeof obj === "string" ) {
422
+ obj = obj.split( " " );
423
+ }
424
+ if ( Array.isArray( obj ) ) {
425
+ obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
426
+ }
427
+ if ( "left" in obj ) {
428
+ this.offset.click.left = obj.left + this.margins.left;
429
+ }
430
+ if ( "right" in obj ) {
431
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
432
+ }
433
+ if ( "top" in obj ) {
434
+ this.offset.click.top = obj.top + this.margins.top;
435
+ }
436
+ if ( "bottom" in obj ) {
437
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
438
+ }
439
+ },
440
+
441
+ _isRootNode: function( element ) {
442
+ return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
443
+ },
444
+
445
+ _getParentOffset: function() {
446
+
447
+ //Get the offsetParent and cache its position
448
+ var po = this.offsetParent.offset(),
449
+ document = this.document[ 0 ];
450
+
451
+ // This is a special case where we need to modify a offset calculated on start, since the
452
+ // following happened:
453
+ // 1. The position of the helper is absolute, so it's position is calculated based on the
454
+ // next positioned parent
455
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
456
+ // the document, which means that the scroll is included in the initial calculation of the
457
+ // offset of the parent, and never recalculated upon drag
458
+ if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
459
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
460
+ po.left += this.scrollParent.scrollLeft();
461
+ po.top += this.scrollParent.scrollTop();
462
+ }
463
+
464
+ if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
465
+ po = { top: 0, left: 0 };
466
+ }
467
+
468
+ return {
469
+ top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
470
+ left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
471
+ };
472
+
473
+ },
474
+
475
+ _getRelativeOffset: function() {
476
+ if ( this.cssPosition !== "relative" ) {
477
+ return { top: 0, left: 0 };
478
+ }
479
+
480
+ var p = this.element.position(),
481
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
482
+
483
+ return {
484
+ top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
485
+ ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
486
+ left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
487
+ ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
488
+ };
489
+
490
+ },
491
+
492
+ _cacheMargins: function() {
493
+ this.margins = {
494
+ left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
495
+ top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
496
+ right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
497
+ bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
498
+ };
499
+ },
500
+
501
+ _cacheHelperProportions: function() {
502
+ this.helperProportions = {
503
+ width: this.helper.outerWidth(),
504
+ height: this.helper.outerHeight()
505
+ };
506
+ },
507
+
508
+ _setContainment: function() {
509
+
510
+ var isUserScrollable, c, ce,
511
+ o = this.options,
512
+ document = this.document[ 0 ];
513
+
514
+ this.relativeContainer = null;
515
+
516
+ if ( !o.containment ) {
517
+ this.containment = null;
518
+ return;
519
+ }
520
+
521
+ if ( o.containment === "window" ) {
522
+ this.containment = [
523
+ $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
524
+ $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
525
+ $( window ).scrollLeft() + $( window ).width() -
526
+ this.helperProportions.width - this.margins.left,
527
+ $( window ).scrollTop() +
528
+ ( $( window ).height() || document.body.parentNode.scrollHeight ) -
529
+ this.helperProportions.height - this.margins.top
530
+ ];
531
+ return;
532
+ }
533
+
534
+ if ( o.containment === "document" ) {
535
+ this.containment = [
536
+ 0,
537
+ 0,
538
+ $( document ).width() - this.helperProportions.width - this.margins.left,
539
+ ( $( document ).height() || document.body.parentNode.scrollHeight ) -
540
+ this.helperProportions.height - this.margins.top
541
+ ];
542
+ return;
543
+ }
544
+
545
+ if ( o.containment.constructor === Array ) {
546
+ this.containment = o.containment;
547
+ return;
548
+ }
549
+
550
+ if ( o.containment === "parent" ) {
551
+ o.containment = this.helper[ 0 ].parentNode;
552
+ }
553
+
554
+ c = $( o.containment );
555
+ ce = c[ 0 ];
556
+
557
+ if ( !ce ) {
558
+ return;
559
+ }
560
+
561
+ isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
562
+
563
+ this.containment = [
564
+ ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
565
+ ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
566
+ ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
567
+ ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
568
+ ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
569
+ ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
570
+ ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
571
+ this.helperProportions.width -
572
+ this.margins.left -
573
+ this.margins.right,
574
+ ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
575
+ ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
576
+ ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
577
+ this.helperProportions.height -
578
+ this.margins.top -
579
+ this.margins.bottom
580
+ ];
581
+ this.relativeContainer = c;
582
+ },
583
+
584
+ _convertPositionTo: function( d, pos ) {
585
+
586
+ if ( !pos ) {
587
+ pos = this.position;
588
+ }
589
+
590
+ var mod = d === "absolute" ? 1 : -1,
591
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
592
+
593
+ return {
594
+ top: (
595
+
596
+ // The absolute mouse position
597
+ pos.top +
598
+
599
+ // Only for relative positioned nodes: Relative offset from element to offset parent
600
+ this.offset.relative.top * mod +
601
+
602
+ // The offsetParent's offset without borders (offset + border)
603
+ this.offset.parent.top * mod -
604
+ ( ( this.cssPosition === "fixed" ?
605
+ -this.offset.scroll.top :
606
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
607
+ ),
608
+ left: (
609
+
610
+ // The absolute mouse position
611
+ pos.left +
612
+
613
+ // Only for relative positioned nodes: Relative offset from element to offset parent
614
+ this.offset.relative.left * mod +
615
+
616
+ // The offsetParent's offset without borders (offset + border)
617
+ this.offset.parent.left * mod -
618
+ ( ( this.cssPosition === "fixed" ?
619
+ -this.offset.scroll.left :
620
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
621
+ )
622
+ };
623
+
624
+ },
625
+
626
+ _generatePosition: function( event, constrainPosition ) {
627
+
628
+ var containment, co, top, left,
629
+ o = this.options,
630
+ scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
631
+ pageX = event.pageX,
632
+ pageY = event.pageY;
633
+
634
+ // Cache the scroll
635
+ if ( !scrollIsRootNode || !this.offset.scroll ) {
636
+ this.offset.scroll = {
637
+ top: this.scrollParent.scrollTop(),
638
+ left: this.scrollParent.scrollLeft()
639
+ };
640
+ }
641
+
642
+ /*
643
+ * - Position constraining -
644
+ * Constrain the position to a mix of grid, containment.
645
+ */
646
+
647
+ // If we are not dragging yet, we won't check for options
648
+ if ( constrainPosition ) {
649
+ if ( this.containment ) {
650
+ if ( this.relativeContainer ) {
651
+ co = this.relativeContainer.offset();
652
+ containment = [
653
+ this.containment[ 0 ] + co.left,
654
+ this.containment[ 1 ] + co.top,
655
+ this.containment[ 2 ] + co.left,
656
+ this.containment[ 3 ] + co.top
657
+ ];
658
+ } else {
659
+ containment = this.containment;
660
+ }
661
+
662
+ if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
663
+ pageX = containment[ 0 ] + this.offset.click.left;
664
+ }
665
+ if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
666
+ pageY = containment[ 1 ] + this.offset.click.top;
667
+ }
668
+ if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
669
+ pageX = containment[ 2 ] + this.offset.click.left;
670
+ }
671
+ if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
672
+ pageY = containment[ 3 ] + this.offset.click.top;
673
+ }
674
+ }
675
+
676
+ if ( o.grid ) {
677
+
678
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
679
+ // argument errors in IE (see ticket #6950)
680
+ top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
681
+ this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
682
+ pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
683
+ top - this.offset.click.top > containment[ 3 ] ) ?
684
+ top :
685
+ ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
686
+ top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
687
+
688
+ left = o.grid[ 0 ] ? this.originalPageX +
689
+ Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
690
+ this.originalPageX;
691
+ pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
692
+ left - this.offset.click.left > containment[ 2 ] ) ?
693
+ left :
694
+ ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
695
+ left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
696
+ }
697
+
698
+ if ( o.axis === "y" ) {
699
+ pageX = this.originalPageX;
700
+ }
701
+
702
+ if ( o.axis === "x" ) {
703
+ pageY = this.originalPageY;
704
+ }
705
+ }
706
+
707
+ return {
708
+ top: (
709
+
710
+ // The absolute mouse position
711
+ pageY -
712
+
713
+ // Click offset (relative to the element)
714
+ this.offset.click.top -
715
+
716
+ // Only for relative positioned nodes: Relative offset from element to offset parent
717
+ this.offset.relative.top -
718
+
719
+ // The offsetParent's offset without borders (offset + border)
720
+ this.offset.parent.top +
721
+ ( this.cssPosition === "fixed" ?
722
+ -this.offset.scroll.top :
723
+ ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
724
+ ),
725
+ left: (
726
+
727
+ // The absolute mouse position
728
+ pageX -
729
+
730
+ // Click offset (relative to the element)
731
+ this.offset.click.left -
732
+
733
+ // Only for relative positioned nodes: Relative offset from element to offset parent
734
+ this.offset.relative.left -
735
+
736
+ // The offsetParent's offset without borders (offset + border)
737
+ this.offset.parent.left +
738
+ ( this.cssPosition === "fixed" ?
739
+ -this.offset.scroll.left :
740
+ ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
741
+ )
742
+ };
743
+
744
+ },
745
+
746
+ _clear: function() {
747
+ this._removeClass( this.helper, "ui-draggable-dragging" );
748
+ if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
749
+ this.helper.remove();
750
+ }
751
+ this.helper = null;
752
+ this.cancelHelperRemoval = false;
753
+ if ( this.destroyOnClear ) {
754
+ this.destroy();
755
+ }
756
+ },
757
+
758
+ // From now on bulk stuff - mainly helpers
759
+
760
+ _trigger: function( type, event, ui ) {
761
+ ui = ui || this._uiHash();
762
+ $.ui.plugin.call( this, type, [ event, ui, this ], true );
763
+
764
+ // Absolute position and offset (see #6884 ) have to be recalculated after plugins
765
+ if ( /^(drag|start|stop)/.test( type ) ) {
766
+ this.positionAbs = this._convertPositionTo( "absolute" );
767
+ ui.offset = this.positionAbs;
768
+ }
769
+ return $.Widget.prototype._trigger.call( this, type, event, ui );
770
+ },
771
+
772
+ plugins: {},
773
+
774
+ _uiHash: function() {
775
+ return {
776
+ helper: this.helper,
777
+ position: this.position,
778
+ originalPosition: this.originalPosition,
779
+ offset: this.positionAbs
780
+ };
781
+ }
782
+
783
+ } );
784
+
785
+ $.ui.plugin.add( "draggable", "connectToSortable", {
786
+ start: function( event, ui, draggable ) {
787
+ var uiSortable = $.extend( {}, ui, {
788
+ item: draggable.element
789
+ } );
790
+
791
+ draggable.sortables = [];
792
+ $( draggable.options.connectToSortable ).each( function() {
793
+ var sortable = $( this ).sortable( "instance" );
794
+
795
+ if ( sortable && !sortable.options.disabled ) {
796
+ draggable.sortables.push( sortable );
797
+
798
+ // RefreshPositions is called at drag start to refresh the containerCache
799
+ // which is used in drag. This ensures it's initialized and synchronized
800
+ // with any changes that might have happened on the page since initialization.
801
+ sortable.refreshPositions();
802
+ sortable._trigger( "activate", event, uiSortable );
803
+ }
804
+ } );
805
+ },
806
+ stop: function( event, ui, draggable ) {
807
+ var uiSortable = $.extend( {}, ui, {
808
+ item: draggable.element
809
+ } );
810
+
811
+ draggable.cancelHelperRemoval = false;
812
+
813
+ $.each( draggable.sortables, function() {
814
+ var sortable = this;
815
+
816
+ if ( sortable.isOver ) {
817
+ sortable.isOver = 0;
818
+
819
+ // Allow this sortable to handle removing the helper
820
+ draggable.cancelHelperRemoval = true;
821
+ sortable.cancelHelperRemoval = false;
822
+
823
+ // Use _storedCSS To restore properties in the sortable,
824
+ // as this also handles revert (#9675) since the draggable
825
+ // may have modified them in unexpected ways (#8809)
826
+ sortable._storedCSS = {
827
+ position: sortable.placeholder.css( "position" ),
828
+ top: sortable.placeholder.css( "top" ),
829
+ left: sortable.placeholder.css( "left" )
830
+ };
831
+
832
+ sortable._mouseStop( event );
833
+
834
+ // Once drag has ended, the sortable should return to using
835
+ // its original helper, not the shared helper from draggable
836
+ sortable.options.helper = sortable.options._helper;
837
+ } else {
838
+
839
+ // Prevent this Sortable from removing the helper.
840
+ // However, don't set the draggable to remove the helper
841
+ // either as another connected Sortable may yet handle the removal.
842
+ sortable.cancelHelperRemoval = true;
843
+
844
+ sortable._trigger( "deactivate", event, uiSortable );
845
+ }
846
+ } );
847
+ },
848
+ drag: function( event, ui, draggable ) {
849
+ $.each( draggable.sortables, function() {
850
+ var innermostIntersecting = false,
851
+ sortable = this;
852
+
853
+ // Copy over variables that sortable's _intersectsWith uses
854
+ sortable.positionAbs = draggable.positionAbs;
855
+ sortable.helperProportions = draggable.helperProportions;
856
+ sortable.offset.click = draggable.offset.click;
857
+
858
+ if ( sortable._intersectsWith( sortable.containerCache ) ) {
859
+ innermostIntersecting = true;
860
+
861
+ $.each( draggable.sortables, function() {
862
+
863
+ // Copy over variables that sortable's _intersectsWith uses
864
+ this.positionAbs = draggable.positionAbs;
865
+ this.helperProportions = draggable.helperProportions;
866
+ this.offset.click = draggable.offset.click;
867
+
868
+ if ( this !== sortable &&
869
+ this._intersectsWith( this.containerCache ) &&
870
+ $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
871
+ innermostIntersecting = false;
872
+ }
873
+
874
+ return innermostIntersecting;
875
+ } );
876
+ }
877
+
878
+ if ( innermostIntersecting ) {
879
+
880
+ // If it intersects, we use a little isOver variable and set it once,
881
+ // so that the move-in stuff gets fired only once.
882
+ if ( !sortable.isOver ) {
883
+ sortable.isOver = 1;
884
+
885
+ // Store draggable's parent in case we need to reappend to it later.
886
+ draggable._parent = ui.helper.parent();
887
+
888
+ sortable.currentItem = ui.helper
889
+ .appendTo( sortable.element )
890
+ .data( "ui-sortable-item", true );
891
+
892
+ // Store helper option to later restore it
893
+ sortable.options._helper = sortable.options.helper;
894
+
895
+ sortable.options.helper = function() {
896
+ return ui.helper[ 0 ];
897
+ };
898
+
899
+ // Fire the start events of the sortable with our passed browser event,
900
+ // and our own helper (so it doesn't create a new one)
901
+ event.target = sortable.currentItem[ 0 ];
902
+ sortable._mouseCapture( event, true );
903
+ sortable._mouseStart( event, true, true );
904
+
905
+ // Because the browser event is way off the new appended portlet,
906
+ // modify necessary variables to reflect the changes
907
+ sortable.offset.click.top = draggable.offset.click.top;
908
+ sortable.offset.click.left = draggable.offset.click.left;
909
+ sortable.offset.parent.left -= draggable.offset.parent.left -
910
+ sortable.offset.parent.left;
911
+ sortable.offset.parent.top -= draggable.offset.parent.top -
912
+ sortable.offset.parent.top;
913
+
914
+ draggable._trigger( "toSortable", event );
915
+
916
+ // Inform draggable that the helper is in a valid drop zone,
917
+ // used solely in the revert option to handle "valid/invalid".
918
+ draggable.dropped = sortable.element;
919
+
920
+ // Need to refreshPositions of all sortables in the case that
921
+ // adding to one sortable changes the location of the other sortables (#9675)
922
+ $.each( draggable.sortables, function() {
923
+ this.refreshPositions();
924
+ } );
925
+
926
+ // Hack so receive/update callbacks work (mostly)
927
+ draggable.currentItem = draggable.element;
928
+ sortable.fromOutside = draggable;
929
+ }
930
+
931
+ if ( sortable.currentItem ) {
932
+ sortable._mouseDrag( event );
933
+
934
+ // Copy the sortable's position because the draggable's can potentially reflect
935
+ // a relative position, while sortable is always absolute, which the dragged
936
+ // element has now become. (#8809)
937
+ ui.position = sortable.position;
938
+ }
939
+ } else {
940
+
941
+ // If it doesn't intersect with the sortable, and it intersected before,
942
+ // we fake the drag stop of the sortable, but make sure it doesn't remove
943
+ // the helper by using cancelHelperRemoval.
944
+ if ( sortable.isOver ) {
945
+
946
+ sortable.isOver = 0;
947
+ sortable.cancelHelperRemoval = true;
948
+
949
+ // Calling sortable's mouseStop would trigger a revert,
950
+ // so revert must be temporarily false until after mouseStop is called.
951
+ sortable.options._revert = sortable.options.revert;
952
+ sortable.options.revert = false;
953
+
954
+ sortable._trigger( "out", event, sortable._uiHash( sortable ) );
955
+ sortable._mouseStop( event, true );
956
+
957
+ // Restore sortable behaviors that were modfied
958
+ // when the draggable entered the sortable area (#9481)
959
+ sortable.options.revert = sortable.options._revert;
960
+ sortable.options.helper = sortable.options._helper;
961
+
962
+ if ( sortable.placeholder ) {
963
+ sortable.placeholder.remove();
964
+ }
965
+
966
+ // Restore and recalculate the draggable's offset considering the sortable
967
+ // may have modified them in unexpected ways. (#8809, #10669)
968
+ ui.helper.appendTo( draggable._parent );
969
+ draggable._refreshOffsets( event );
970
+ ui.position = draggable._generatePosition( event, true );
971
+
972
+ draggable._trigger( "fromSortable", event );
973
+
974
+ // Inform draggable that the helper is no longer in a valid drop zone
975
+ draggable.dropped = false;
976
+
977
+ // Need to refreshPositions of all sortables just in case removing
978
+ // from one sortable changes the location of other sortables (#9675)
979
+ $.each( draggable.sortables, function() {
980
+ this.refreshPositions();
981
+ } );
982
+ }
983
+ }
984
+ } );
985
+ }
986
+ } );
987
+
988
+ $.ui.plugin.add( "draggable", "cursor", {
989
+ start: function( event, ui, instance ) {
990
+ var t = $( "body" ),
991
+ o = instance.options;
992
+
993
+ if ( t.css( "cursor" ) ) {
994
+ o._cursor = t.css( "cursor" );
995
+ }
996
+ t.css( "cursor", o.cursor );
997
+ },
998
+ stop: function( event, ui, instance ) {
999
+ var o = instance.options;
1000
+ if ( o._cursor ) {
1001
+ $( "body" ).css( "cursor", o._cursor );
1002
+ }
1003
+ }
1004
+ } );
1005
+
1006
+ $.ui.plugin.add( "draggable", "opacity", {
1007
+ start: function( event, ui, instance ) {
1008
+ var t = $( ui.helper ),
1009
+ o = instance.options;
1010
+ if ( t.css( "opacity" ) ) {
1011
+ o._opacity = t.css( "opacity" );
1012
+ }
1013
+ t.css( "opacity", o.opacity );
1014
+ },
1015
+ stop: function( event, ui, instance ) {
1016
+ var o = instance.options;
1017
+ if ( o._opacity ) {
1018
+ $( ui.helper ).css( "opacity", o._opacity );
1019
+ }
1020
+ }
1021
+ } );
1022
+
1023
+ $.ui.plugin.add( "draggable", "scroll", {
1024
+ start: function( event, ui, i ) {
1025
+ if ( !i.scrollParentNotHidden ) {
1026
+ i.scrollParentNotHidden = i.helper.scrollParent( false );
1027
+ }
1028
+
1029
+ if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
1030
+ i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
1031
+ i.overflowOffset = i.scrollParentNotHidden.offset();
1032
+ }
1033
+ },
1034
+ drag: function( event, ui, i ) {
1035
+
1036
+ var o = i.options,
1037
+ scrolled = false,
1038
+ scrollParent = i.scrollParentNotHidden[ 0 ],
1039
+ document = i.document[ 0 ];
1040
+
1041
+ if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
1042
+ if ( !o.axis || o.axis !== "x" ) {
1043
+ if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
1044
+ o.scrollSensitivity ) {
1045
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
1046
+ } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
1047
+ scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
1048
+ }
1049
+ }
1050
+
1051
+ if ( !o.axis || o.axis !== "y" ) {
1052
+ if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
1053
+ o.scrollSensitivity ) {
1054
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
1055
+ } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
1056
+ scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
1057
+ }
1058
+ }
1059
+
1060
+ } else {
1061
+
1062
+ if ( !o.axis || o.axis !== "x" ) {
1063
+ if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
1064
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
1065
+ } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
1066
+ o.scrollSensitivity ) {
1067
+ scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
1068
+ }
1069
+ }
1070
+
1071
+ if ( !o.axis || o.axis !== "y" ) {
1072
+ if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
1073
+ scrolled = $( document ).scrollLeft(
1074
+ $( document ).scrollLeft() - o.scrollSpeed
1075
+ );
1076
+ } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
1077
+ o.scrollSensitivity ) {
1078
+ scrolled = $( document ).scrollLeft(
1079
+ $( document ).scrollLeft() + o.scrollSpeed
1080
+ );
1081
+ }
1082
+ }
1083
+
1084
+ }
1085
+
1086
+ if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
1087
+ $.ui.ddmanager.prepareOffsets( i, event );
1088
+ }
1089
+
1090
+ }
1091
+ } );
1092
+
1093
+ $.ui.plugin.add( "draggable", "snap", {
1094
+ start: function( event, ui, i ) {
1095
+
1096
+ var o = i.options;
1097
+
1098
+ i.snapElements = [];
1099
+
1100
+ $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
1101
+ .each( function() {
1102
+ var $t = $( this ),
1103
+ $o = $t.offset();
1104
+ if ( this !== i.element[ 0 ] ) {
1105
+ i.snapElements.push( {
1106
+ item: this,
1107
+ width: $t.outerWidth(), height: $t.outerHeight(),
1108
+ top: $o.top, left: $o.left
1109
+ } );
1110
+ }
1111
+ } );
1112
+
1113
+ },
1114
+ drag: function( event, ui, inst ) {
1115
+
1116
+ var ts, bs, ls, rs, l, r, t, b, i, first,
1117
+ o = inst.options,
1118
+ d = o.snapTolerance,
1119
+ x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1120
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1121
+
1122
+ for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
1123
+
1124
+ l = inst.snapElements[ i ].left - inst.margins.left;
1125
+ r = l + inst.snapElements[ i ].width;
1126
+ t = inst.snapElements[ i ].top - inst.margins.top;
1127
+ b = t + inst.snapElements[ i ].height;
1128
+
1129
+ if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
1130
+ !$.contains( inst.snapElements[ i ].item.ownerDocument,
1131
+ inst.snapElements[ i ].item ) ) {
1132
+ if ( inst.snapElements[ i ].snapping ) {
1133
+ if ( inst.options.snap.release ) {
1134
+ inst.options.snap.release.call(
1135
+ inst.element,
1136
+ event,
1137
+ $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
1138
+ );
1139
+ }
1140
+ }
1141
+ inst.snapElements[ i ].snapping = false;
1142
+ continue;
1143
+ }
1144
+
1145
+ if ( o.snapMode !== "inner" ) {
1146
+ ts = Math.abs( t - y2 ) <= d;
1147
+ bs = Math.abs( b - y1 ) <= d;
1148
+ ls = Math.abs( l - x2 ) <= d;
1149
+ rs = Math.abs( r - x1 ) <= d;
1150
+ if ( ts ) {
1151
+ ui.position.top = inst._convertPositionTo( "relative", {
1152
+ top: t - inst.helperProportions.height,
1153
+ left: 0
1154
+ } ).top;
1155
+ }
1156
+ if ( bs ) {
1157
+ ui.position.top = inst._convertPositionTo( "relative", {
1158
+ top: b,
1159
+ left: 0
1160
+ } ).top;
1161
+ }
1162
+ if ( ls ) {
1163
+ ui.position.left = inst._convertPositionTo( "relative", {
1164
+ top: 0,
1165
+ left: l - inst.helperProportions.width
1166
+ } ).left;
1167
+ }
1168
+ if ( rs ) {
1169
+ ui.position.left = inst._convertPositionTo( "relative", {
1170
+ top: 0,
1171
+ left: r
1172
+ } ).left;
1173
+ }
1174
+ }
1175
+
1176
+ first = ( ts || bs || ls || rs );
1177
+
1178
+ if ( o.snapMode !== "outer" ) {
1179
+ ts = Math.abs( t - y1 ) <= d;
1180
+ bs = Math.abs( b - y2 ) <= d;
1181
+ ls = Math.abs( l - x1 ) <= d;
1182
+ rs = Math.abs( r - x2 ) <= d;
1183
+ if ( ts ) {
1184
+ ui.position.top = inst._convertPositionTo( "relative", {
1185
+ top: t,
1186
+ left: 0
1187
+ } ).top;
1188
+ }
1189
+ if ( bs ) {
1190
+ ui.position.top = inst._convertPositionTo( "relative", {
1191
+ top: b - inst.helperProportions.height,
1192
+ left: 0
1193
+ } ).top;
1194
+ }
1195
+ if ( ls ) {
1196
+ ui.position.left = inst._convertPositionTo( "relative", {
1197
+ top: 0,
1198
+ left: l
1199
+ } ).left;
1200
+ }
1201
+ if ( rs ) {
1202
+ ui.position.left = inst._convertPositionTo( "relative", {
1203
+ top: 0,
1204
+ left: r - inst.helperProportions.width
1205
+ } ).left;
1206
+ }
1207
+ }
1208
+
1209
+ if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
1210
+ if ( inst.options.snap.snap ) {
1211
+ inst.options.snap.snap.call(
1212
+ inst.element,
1213
+ event,
1214
+ $.extend( inst._uiHash(), {
1215
+ snapItem: inst.snapElements[ i ].item
1216
+ } ) );
1217
+ }
1218
+ }
1219
+ inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
1220
+
1221
+ }
1222
+
1223
+ }
1224
+ } );
1225
+
1226
+ $.ui.plugin.add( "draggable", "stack", {
1227
+ start: function( event, ui, instance ) {
1228
+ var min,
1229
+ o = instance.options,
1230
+ group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
1231
+ return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
1232
+ ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
1233
+ } );
1234
+
1235
+ if ( !group.length ) {
1236
+ return;
1237
+ }
1238
+
1239
+ min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
1240
+ $( group ).each( function( i ) {
1241
+ $( this ).css( "zIndex", min + i );
1242
+ } );
1243
+ this.css( "zIndex", ( min + group.length ) );
1244
+ }
1245
+ } );
1246
+
1247
+ $.ui.plugin.add( "draggable", "zIndex", {
1248
+ start: function( event, ui, instance ) {
1249
+ var t = $( ui.helper ),
1250
+ o = instance.options;
1251
+
1252
+ if ( t.css( "zIndex" ) ) {
1253
+ o._zIndex = t.css( "zIndex" );
1254
+ }
1255
+ t.css( "zIndex", o.zIndex );
1256
+ },
1257
+ stop: function( event, ui, instance ) {
1258
+ var o = instance.options;
1259
+
1260
+ if ( o._zIndex ) {
1261
+ $( ui.helper ).css( "zIndex", o._zIndex );
1262
+ }
1263
+ }
1264
+ } );
1265
+
1266
+ return $.ui.draggable;
1267
+
1268
+ } );