jquery-ui-rails-dox-fork 7.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +2 -0
  5. data/CONTRIBUTING.txt +30 -0
  6. data/Gemfile +3 -0
  7. data/History.md +172 -0
  8. data/License.txt +2 -0
  9. data/README.md +311 -0
  10. data/Rakefile +263 -0
  11. data/VERSIONS.md +41 -0
  12. data/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  13. data/app/assets/images/jquery-ui/ui-icons_444444_256x240.png +0 -0
  14. data/app/assets/images/jquery-ui/ui-icons_555555_256x240.png +0 -0
  15. data/app/assets/images/jquery-ui/ui-icons_777620_256x240.png +0 -0
  16. data/app/assets/images/jquery-ui/ui-icons_777777_256x240.png +0 -0
  17. data/app/assets/images/jquery-ui/ui-icons_cc0000_256x240.png +0 -0
  18. data/app/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  19. data/app/assets/javascripts/jquery-ui/core.js +15 -0
  20. data/app/assets/javascripts/jquery-ui/data.js +45 -0
  21. data/app/assets/javascripts/jquery-ui/disable-selection.js +51 -0
  22. data/app/assets/javascripts/jquery-ui/effect.all.js +15 -0
  23. data/app/assets/javascripts/jquery-ui/effect.js +975 -0
  24. data/app/assets/javascripts/jquery-ui/effects/effect-blind.js +76 -0
  25. data/app/assets/javascripts/jquery-ui/effects/effect-bounce.js +116 -0
  26. data/app/assets/javascripts/jquery-ui/effects/effect-clip.js +71 -0
  27. data/app/assets/javascripts/jquery-ui/effects/effect-drop.js +75 -0
  28. data/app/assets/javascripts/jquery-ui/effects/effect-explode.js +117 -0
  29. data/app/assets/javascripts/jquery-ui/effects/effect-fade.js +53 -0
  30. data/app/assets/javascripts/jquery-ui/effects/effect-fold.js +95 -0
  31. data/app/assets/javascripts/jquery-ui/effects/effect-highlight.js +63 -0
  32. data/app/assets/javascripts/jquery-ui/effects/effect-puff.js +49 -0
  33. data/app/assets/javascripts/jquery-ui/effects/effect-pulsate.js +70 -0
  34. data/app/assets/javascripts/jquery-ui/effects/effect-scale.js +63 -0
  35. data/app/assets/javascripts/jquery-ui/effects/effect-shake.js +80 -0
  36. data/app/assets/javascripts/jquery-ui/effects/effect-size.js +199 -0
  37. data/app/assets/javascripts/jquery-ui/effects/effect-slide.js +82 -0
  38. data/app/assets/javascripts/jquery-ui/effects/effect-transfer.js +46 -0
  39. data/app/assets/javascripts/jquery-ui/focusable.js +89 -0
  40. data/app/assets/javascripts/jquery-ui/form-reset-mixin.js +83 -0
  41. data/app/assets/javascripts/jquery-ui/form.js +25 -0
  42. data/app/assets/javascripts/jquery-ui/i18n/datepicker-af.js +40 -0
  43. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ar-DZ.js +42 -0
  44. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ar.js +42 -0
  45. data/app/assets/javascripts/jquery-ui/i18n/datepicker-az.js +40 -0
  46. data/app/assets/javascripts/jquery-ui/i18n/datepicker-be.js +40 -0
  47. data/app/assets/javascripts/jquery-ui/i18n/datepicker-bg.js +41 -0
  48. data/app/assets/javascripts/jquery-ui/i18n/datepicker-bs.js +40 -0
  49. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ca.js +40 -0
  50. data/app/assets/javascripts/jquery-ui/i18n/datepicker-cs.js +40 -0
  51. data/app/assets/javascripts/jquery-ui/i18n/datepicker-cy-GB.js +48 -0
  52. data/app/assets/javascripts/jquery-ui/i18n/datepicker-da.js +40 -0
  53. data/app/assets/javascripts/jquery-ui/i18n/datepicker-de-AT.js +41 -0
  54. data/app/assets/javascripts/jquery-ui/i18n/datepicker-de.js +40 -0
  55. data/app/assets/javascripts/jquery-ui/i18n/datepicker-el.js +40 -0
  56. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-AU.js +40 -0
  57. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-GB.js +40 -0
  58. data/app/assets/javascripts/jquery-ui/i18n/datepicker-en-NZ.js +40 -0
  59. data/app/assets/javascripts/jquery-ui/i18n/datepicker-eo.js +40 -0
  60. data/app/assets/javascripts/jquery-ui/i18n/datepicker-es.js +40 -0
  61. data/app/assets/javascripts/jquery-ui/i18n/datepicker-et.js +48 -0
  62. data/app/assets/javascripts/jquery-ui/i18n/datepicker-eu.js +39 -0
  63. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fa.js +76 -0
  64. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fi.js +40 -0
  65. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fo.js +48 -0
  66. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr-CA.js +40 -0
  67. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr-CH.js +40 -0
  68. data/app/assets/javascripts/jquery-ui/i18n/datepicker-fr.js +42 -0
  69. data/app/assets/javascripts/jquery-ui/i18n/datepicker-gl.js +40 -0
  70. data/app/assets/javascripts/jquery-ui/i18n/datepicker-he.js +40 -0
  71. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hi.js +40 -0
  72. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hr.js +40 -0
  73. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hu.js +39 -0
  74. data/app/assets/javascripts/jquery-ui/i18n/datepicker-hy.js +40 -0
  75. data/app/assets/javascripts/jquery-ui/i18n/datepicker-id.js +41 -0
  76. data/app/assets/javascripts/jquery-ui/i18n/datepicker-is.js +48 -0
  77. data/app/assets/javascripts/jquery-ui/i18n/datepicker-it-CH.js +40 -0
  78. data/app/assets/javascripts/jquery-ui/i18n/datepicker-it.js +40 -0
  79. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ja.js +40 -0
  80. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ka.js +51 -0
  81. data/app/assets/javascripts/jquery-ui/i18n/datepicker-kk.js +40 -0
  82. data/app/assets/javascripts/jquery-ui/i18n/datepicker-km.js +40 -0
  83. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ko.js +40 -0
  84. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ky.js +41 -0
  85. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lb.js +48 -0
  86. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lt.js +48 -0
  87. data/app/assets/javascripts/jquery-ui/i18n/datepicker-lv.js +48 -0
  88. data/app/assets/javascripts/jquery-ui/i18n/datepicker-mk.js +40 -0
  89. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ml.js +40 -0
  90. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ms.js +40 -0
  91. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nb.js +52 -0
  92. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nl-BE.js +40 -0
  93. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nl.js +40 -0
  94. data/app/assets/javascripts/jquery-ui/i18n/datepicker-nn.js +52 -0
  95. data/app/assets/javascripts/jquery-ui/i18n/datepicker-no.js +53 -0
  96. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pl.js +40 -0
  97. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pt-BR.js +48 -0
  98. data/app/assets/javascripts/jquery-ui/i18n/datepicker-pt.js +47 -0
  99. data/app/assets/javascripts/jquery-ui/i18n/datepicker-rm.js +64 -0
  100. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ro.js +43 -0
  101. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ru.js +40 -0
  102. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sk.js +40 -0
  103. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sl.js +41 -0
  104. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sq.js +40 -0
  105. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sr-SR.js +40 -0
  106. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sr.js +40 -0
  107. data/app/assets/javascripts/jquery-ui/i18n/datepicker-sv.js +40 -0
  108. data/app/assets/javascripts/jquery-ui/i18n/datepicker-ta.js +56 -0
  109. data/app/assets/javascripts/jquery-ui/i18n/datepicker-th.js +40 -0
  110. data/app/assets/javascripts/jquery-ui/i18n/datepicker-tj.js +40 -0
  111. data/app/assets/javascripts/jquery-ui/i18n/datepicker-tr.js +40 -0
  112. data/app/assets/javascripts/jquery-ui/i18n/datepicker-uk.js +41 -0
  113. data/app/assets/javascripts/jquery-ui/i18n/datepicker-vi.js +40 -0
  114. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-CN.js +40 -0
  115. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-HK.js +40 -0
  116. data/app/assets/javascripts/jquery-ui/i18n/datepicker-zh-TW.js +40 -0
  117. data/app/assets/javascripts/jquery-ui/ie.js +20 -0
  118. data/app/assets/javascripts/jquery-ui/jquery-patch.js +91 -0
  119. data/app/assets/javascripts/jquery-ui/jquery-var-for-color.js +24 -0
  120. data/app/assets/javascripts/jquery-ui/keycode.js +51 -0
  121. data/app/assets/javascripts/jquery-ui/labels.js +71 -0
  122. data/app/assets/javascripts/jquery-ui/plugin.js +49 -0
  123. data/app/assets/javascripts/jquery-ui/position.js +513 -0
  124. data/app/assets/javascripts/jquery-ui/safe-active-element.js +46 -0
  125. data/app/assets/javascripts/jquery-ui/safe-blur.js +27 -0
  126. data/app/assets/javascripts/jquery-ui/scroll-parent.js +50 -0
  127. data/app/assets/javascripts/jquery-ui/tabbable.js +41 -0
  128. data/app/assets/javascripts/jquery-ui/unique-id.js +54 -0
  129. data/app/assets/javascripts/jquery-ui/vendor/jquery-color/jquery.color.js +722 -0
  130. data/app/assets/javascripts/jquery-ui/version.js +20 -0
  131. data/app/assets/javascripts/jquery-ui/widget.js +758 -0
  132. data/app/assets/javascripts/jquery-ui/widgets/accordion.js +627 -0
  133. data/app/assets/javascripts/jquery-ui/widgets/autocomplete.js +685 -0
  134. data/app/assets/javascripts/jquery-ui/widgets/button.js +454 -0
  135. data/app/assets/javascripts/jquery-ui/widgets/checkboxradio.js +294 -0
  136. data/app/assets/javascripts/jquery-ui/widgets/controlgroup.js +304 -0
  137. data/app/assets/javascripts/jquery-ui/widgets/datepicker.js +2243 -0
  138. data/app/assets/javascripts/jquery-ui/widgets/dialog.js +968 -0
  139. data/app/assets/javascripts/jquery-ui/widgets/draggable.js +1268 -0
  140. data/app/assets/javascripts/jquery-ui/widgets/droppable.js +508 -0
  141. data/app/assets/javascripts/jquery-ui/widgets/menu.js +720 -0
  142. data/app/assets/javascripts/jquery-ui/widgets/mouse.js +241 -0
  143. data/app/assets/javascripts/jquery-ui/widgets/progressbar.js +184 -0
  144. data/app/assets/javascripts/jquery-ui/widgets/resizable.js +1225 -0
  145. data/app/assets/javascripts/jquery-ui/widgets/selectable.js +321 -0
  146. data/app/assets/javascripts/jquery-ui/widgets/selectmenu.js +702 -0
  147. data/app/assets/javascripts/jquery-ui/widgets/slider.js +760 -0
  148. data/app/assets/javascripts/jquery-ui/widgets/sortable.js +1622 -0
  149. data/app/assets/javascripts/jquery-ui/widgets/spinner.js +588 -0
  150. data/app/assets/javascripts/jquery-ui/widgets/tabs.js +931 -0
  151. data/app/assets/javascripts/jquery-ui/widgets/tooltip.js +533 -0
  152. data/app/assets/javascripts/jquery-ui.js +57 -0
  153. data/app/assets/stylesheets/jquery-ui/accordion.css +26 -0
  154. data/app/assets/stylesheets/jquery-ui/all.css +14 -0
  155. data/app/assets/stylesheets/jquery-ui/autocomplete.css +19 -0
  156. data/app/assets/stylesheets/jquery-ui/base.css +32 -0
  157. data/app/assets/stylesheets/jquery-ui/button.css +85 -0
  158. data/app/assets/stylesheets/jquery-ui/checkboxradio.css +37 -0
  159. data/app/assets/stylesheets/jquery-ui/controlgroup.css +68 -0
  160. data/app/assets/stylesheets/jquery-ui/core.css +100 -0
  161. data/app/assets/stylesheets/jquery-ui/datepicker.css +188 -0
  162. data/app/assets/stylesheets/jquery-ui/dialog.css +104 -0
  163. data/app/assets/stylesheets/jquery-ui/draggable.css +15 -0
  164. data/app/assets/stylesheets/jquery-ui/menu.css +67 -0
  165. data/app/assets/stylesheets/jquery-ui/progressbar.css +31 -0
  166. data/app/assets/stylesheets/jquery-ui/resizable.css +81 -0
  167. data/app/assets/stylesheets/jquery-ui/selectable.css +20 -0
  168. data/app/assets/stylesheets/jquery-ui/selectmenu.css +53 -0
  169. data/app/assets/stylesheets/jquery-ui/slider.css +78 -0
  170. data/app/assets/stylesheets/jquery-ui/sortable.css +15 -0
  171. data/app/assets/stylesheets/jquery-ui/spinner.css +55 -0
  172. data/app/assets/stylesheets/jquery-ui/tabs.css +54 -0
  173. data/app/assets/stylesheets/jquery-ui/theme.css.erb +456 -0
  174. data/app/assets/stylesheets/jquery-ui/tooltip.css +22 -0
  175. data/app/assets/stylesheets/jquery-ui.css +1 -0
  176. data/lib/jquery/ui/rails/engine.rb +8 -0
  177. data/lib/jquery/ui/rails/version.rb +8 -0
  178. data/lib/jquery/ui/rails.rb +2 -0
  179. data/lib/jquery-ui-rails.rb +1 -0
  180. metadata +250 -0
@@ -0,0 +1,1622 @@
1
+ //= require jquery-ui/widgets/mouse
2
+ //= require jquery-ui/data
3
+ //= require jquery-ui/ie
4
+ //= require jquery-ui/scroll-parent
5
+ //= require jquery-ui/version
6
+ //= require jquery-ui/widget
7
+
8
+ /*!
9
+ * jQuery UI Sortable 1.13.2
10
+ * http://jqueryui.com
11
+ *
12
+ * Copyright jQuery Foundation and other contributors
13
+ * Released under the MIT license.
14
+ * http://jquery.org/license
15
+ */
16
+
17
+ //>>label: Sortable
18
+ //>>group: Interactions
19
+ //>>description: Enables items in a list to be sorted using the mouse.
20
+ //>>docs: http://api.jqueryui.com/sortable/
21
+ //>>demos: http://jqueryui.com/sortable/
22
+ //>>css.structure: ../../themes/base/sortable.css
23
+
24
+ ( function( factory ) {
25
+ "use strict";
26
+
27
+ if ( typeof define === "function" && define.amd ) {
28
+
29
+ // AMD. Register as an anonymous module.
30
+ define( [
31
+ "jquery",
32
+ "./mouse",
33
+ "../data",
34
+ "../ie",
35
+ "../scroll-parent",
36
+ "../version",
37
+ "../widget"
38
+ ], factory );
39
+ } else {
40
+
41
+ // Browser globals
42
+ factory( jQuery );
43
+ }
44
+ } )( function( $ ) {
45
+ "use strict";
46
+
47
+ return $.widget( "ui.sortable", $.ui.mouse, {
48
+ version: "1.13.2",
49
+ widgetEventPrefix: "sort",
50
+ ready: false,
51
+ options: {
52
+ appendTo: "parent",
53
+ axis: false,
54
+ connectWith: false,
55
+ containment: false,
56
+ cursor: "auto",
57
+ cursorAt: false,
58
+ dropOnEmpty: true,
59
+ forcePlaceholderSize: false,
60
+ forceHelperSize: false,
61
+ grid: false,
62
+ handle: false,
63
+ helper: "original",
64
+ items: "> *",
65
+ opacity: false,
66
+ placeholder: false,
67
+ revert: false,
68
+ scroll: true,
69
+ scrollSensitivity: 20,
70
+ scrollSpeed: 20,
71
+ scope: "default",
72
+ tolerance: "intersect",
73
+ zIndex: 1000,
74
+
75
+ // Callbacks
76
+ activate: null,
77
+ beforeStop: null,
78
+ change: null,
79
+ deactivate: null,
80
+ out: null,
81
+ over: null,
82
+ receive: null,
83
+ remove: null,
84
+ sort: null,
85
+ start: null,
86
+ stop: null,
87
+ update: null
88
+ },
89
+
90
+ _isOverAxis: function( x, reference, size ) {
91
+ return ( x >= reference ) && ( x < ( reference + size ) );
92
+ },
93
+
94
+ _isFloating: function( item ) {
95
+ return ( /left|right/ ).test( item.css( "float" ) ) ||
96
+ ( /inline|table-cell/ ).test( item.css( "display" ) );
97
+ },
98
+
99
+ _create: function() {
100
+ this.containerCache = {};
101
+ this._addClass( "ui-sortable" );
102
+
103
+ //Get the items
104
+ this.refresh();
105
+
106
+ //Let's determine the parent's offset
107
+ this.offset = this.element.offset();
108
+
109
+ //Initialize mouse events for interaction
110
+ this._mouseInit();
111
+
112
+ this._setHandleClassName();
113
+
114
+ //We're ready to go
115
+ this.ready = true;
116
+
117
+ },
118
+
119
+ _setOption: function( key, value ) {
120
+ this._super( key, value );
121
+
122
+ if ( key === "handle" ) {
123
+ this._setHandleClassName();
124
+ }
125
+ },
126
+
127
+ _setHandleClassName: function() {
128
+ var that = this;
129
+ this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
130
+ $.each( this.items, function() {
131
+ that._addClass(
132
+ this.instance.options.handle ?
133
+ this.item.find( this.instance.options.handle ) :
134
+ this.item,
135
+ "ui-sortable-handle"
136
+ );
137
+ } );
138
+ },
139
+
140
+ _destroy: function() {
141
+ this._mouseDestroy();
142
+
143
+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
144
+ this.items[ i ].item.removeData( this.widgetName + "-item" );
145
+ }
146
+
147
+ return this;
148
+ },
149
+
150
+ _mouseCapture: function( event, overrideHandle ) {
151
+ var currentItem = null,
152
+ validHandle = false,
153
+ that = this;
154
+
155
+ if ( this.reverting ) {
156
+ return false;
157
+ }
158
+
159
+ if ( this.options.disabled || this.options.type === "static" ) {
160
+ return false;
161
+ }
162
+
163
+ //We have to refresh the items data once first
164
+ this._refreshItems( event );
165
+
166
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
167
+ $( event.target ).parents().each( function() {
168
+ if ( $.data( this, that.widgetName + "-item" ) === that ) {
169
+ currentItem = $( this );
170
+ return false;
171
+ }
172
+ } );
173
+ if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
174
+ currentItem = $( event.target );
175
+ }
176
+
177
+ if ( !currentItem ) {
178
+ return false;
179
+ }
180
+ if ( this.options.handle && !overrideHandle ) {
181
+ $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
182
+ if ( this === event.target ) {
183
+ validHandle = true;
184
+ }
185
+ } );
186
+ if ( !validHandle ) {
187
+ return false;
188
+ }
189
+ }
190
+
191
+ this.currentItem = currentItem;
192
+ this._removeCurrentsFromItems();
193
+ return true;
194
+
195
+ },
196
+
197
+ _mouseStart: function( event, overrideHandle, noActivation ) {
198
+
199
+ var i, body,
200
+ o = this.options;
201
+
202
+ this.currentContainer = this;
203
+
204
+ //We only need to call refreshPositions, because the refreshItems call has been moved to
205
+ // mouseCapture
206
+ this.refreshPositions();
207
+
208
+ //Prepare the dragged items parent
209
+ this.appendTo = $( o.appendTo !== "parent" ?
210
+ o.appendTo :
211
+ this.currentItem.parent() );
212
+
213
+ //Create and append the visible helper
214
+ this.helper = this._createHelper( event );
215
+
216
+ //Cache the helper size
217
+ this._cacheHelperProportions();
218
+
219
+ /*
220
+ * - Position generation -
221
+ * This block generates everything position related - it's the core of draggables.
222
+ */
223
+
224
+ //Cache the margins of the original element
225
+ this._cacheMargins();
226
+
227
+ //The element's absolute position on the page minus margins
228
+ this.offset = this.currentItem.offset();
229
+ this.offset = {
230
+ top: this.offset.top - this.margins.top,
231
+ left: this.offset.left - this.margins.left
232
+ };
233
+
234
+ $.extend( this.offset, {
235
+ click: { //Where the click happened, relative to the element
236
+ left: event.pageX - this.offset.left,
237
+ top: event.pageY - this.offset.top
238
+ },
239
+
240
+ // This is a relative to absolute position minus the actual position calculation -
241
+ // only used for relative positioned helper
242
+ relative: this._getRelativeOffset()
243
+ } );
244
+
245
+ // After we get the helper offset, but before we get the parent offset we can
246
+ // change the helper's position to absolute
247
+ // TODO: Still need to figure out a way to make relative sorting possible
248
+ this.helper.css( "position", "absolute" );
249
+ this.cssPosition = this.helper.css( "position" );
250
+
251
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
252
+ if ( o.cursorAt ) {
253
+ this._adjustOffsetFromHelper( o.cursorAt );
254
+ }
255
+
256
+ //Cache the former DOM position
257
+ this.domPosition = {
258
+ prev: this.currentItem.prev()[ 0 ],
259
+ parent: this.currentItem.parent()[ 0 ]
260
+ };
261
+
262
+ // If the helper is not the original, hide the original so it's not playing any role during
263
+ // the drag, won't cause anything bad this way
264
+ if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
265
+ this.currentItem.hide();
266
+ }
267
+
268
+ //Create the placeholder
269
+ this._createPlaceholder();
270
+
271
+ //Get the next scrolling parent
272
+ this.scrollParent = this.placeholder.scrollParent();
273
+
274
+ $.extend( this.offset, {
275
+ parent: this._getParentOffset()
276
+ } );
277
+
278
+ //Set a containment if given in the options
279
+ if ( o.containment ) {
280
+ this._setContainment();
281
+ }
282
+
283
+ if ( o.cursor && o.cursor !== "auto" ) { // cursor option
284
+ body = this.document.find( "body" );
285
+
286
+ // Support: IE
287
+ this.storedCursor = body.css( "cursor" );
288
+ body.css( "cursor", o.cursor );
289
+
290
+ this.storedStylesheet =
291
+ $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
292
+ }
293
+
294
+ // We need to make sure to grab the zIndex before setting the
295
+ // opacity, because setting the opacity to anything lower than 1
296
+ // causes the zIndex to change from "auto" to 0.
297
+ if ( o.zIndex ) { // zIndex option
298
+ if ( this.helper.css( "zIndex" ) ) {
299
+ this._storedZIndex = this.helper.css( "zIndex" );
300
+ }
301
+ this.helper.css( "zIndex", o.zIndex );
302
+ }
303
+
304
+ if ( o.opacity ) { // opacity option
305
+ if ( this.helper.css( "opacity" ) ) {
306
+ this._storedOpacity = this.helper.css( "opacity" );
307
+ }
308
+ this.helper.css( "opacity", o.opacity );
309
+ }
310
+
311
+ //Prepare scrolling
312
+ if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
313
+ this.scrollParent[ 0 ].tagName !== "HTML" ) {
314
+ this.overflowOffset = this.scrollParent.offset();
315
+ }
316
+
317
+ //Call callbacks
318
+ this._trigger( "start", event, this._uiHash() );
319
+
320
+ //Recache the helper size
321
+ if ( !this._preserveHelperProportions ) {
322
+ this._cacheHelperProportions();
323
+ }
324
+
325
+ //Post "activate" events to possible containers
326
+ if ( !noActivation ) {
327
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
328
+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
329
+ }
330
+ }
331
+
332
+ //Prepare possible droppables
333
+ if ( $.ui.ddmanager ) {
334
+ $.ui.ddmanager.current = this;
335
+ }
336
+
337
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
338
+ $.ui.ddmanager.prepareOffsets( this, event );
339
+ }
340
+
341
+ this.dragging = true;
342
+
343
+ this._addClass( this.helper, "ui-sortable-helper" );
344
+
345
+ //Move the helper, if needed
346
+ if ( !this.helper.parent().is( this.appendTo ) ) {
347
+ this.helper.detach().appendTo( this.appendTo );
348
+
349
+ //Update position
350
+ this.offset.parent = this._getParentOffset();
351
+ }
352
+
353
+ //Generate the original position
354
+ this.position = this.originalPosition = this._generatePosition( event );
355
+ this.originalPageX = event.pageX;
356
+ this.originalPageY = event.pageY;
357
+ this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
358
+
359
+ this._mouseDrag( event );
360
+
361
+ return true;
362
+
363
+ },
364
+
365
+ _scroll: function( event ) {
366
+ var o = this.options,
367
+ scrolled = false;
368
+
369
+ if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
370
+ this.scrollParent[ 0 ].tagName !== "HTML" ) {
371
+
372
+ if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
373
+ event.pageY < o.scrollSensitivity ) {
374
+ this.scrollParent[ 0 ].scrollTop =
375
+ scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
376
+ } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
377
+ this.scrollParent[ 0 ].scrollTop =
378
+ scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
379
+ }
380
+
381
+ if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
382
+ event.pageX < o.scrollSensitivity ) {
383
+ this.scrollParent[ 0 ].scrollLeft = scrolled =
384
+ this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
385
+ } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
386
+ this.scrollParent[ 0 ].scrollLeft = scrolled =
387
+ this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
388
+ }
389
+
390
+ } else {
391
+
392
+ if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
393
+ scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
394
+ } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
395
+ o.scrollSensitivity ) {
396
+ scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
397
+ }
398
+
399
+ if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
400
+ scrolled = this.document.scrollLeft(
401
+ this.document.scrollLeft() - o.scrollSpeed
402
+ );
403
+ } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
404
+ o.scrollSensitivity ) {
405
+ scrolled = this.document.scrollLeft(
406
+ this.document.scrollLeft() + o.scrollSpeed
407
+ );
408
+ }
409
+
410
+ }
411
+
412
+ return scrolled;
413
+ },
414
+
415
+ _mouseDrag: function( event ) {
416
+ var i, item, itemElement, intersection,
417
+ o = this.options;
418
+
419
+ //Compute the helpers position
420
+ this.position = this._generatePosition( event );
421
+ this.positionAbs = this._convertPositionTo( "absolute" );
422
+
423
+ //Set the helper position
424
+ if ( !this.options.axis || this.options.axis !== "y" ) {
425
+ this.helper[ 0 ].style.left = this.position.left + "px";
426
+ }
427
+ if ( !this.options.axis || this.options.axis !== "x" ) {
428
+ this.helper[ 0 ].style.top = this.position.top + "px";
429
+ }
430
+
431
+ //Do scrolling
432
+ if ( o.scroll ) {
433
+ if ( this._scroll( event ) !== false ) {
434
+
435
+ //Update item positions used in position checks
436
+ this._refreshItemPositions( true );
437
+
438
+ if ( $.ui.ddmanager && !o.dropBehaviour ) {
439
+ $.ui.ddmanager.prepareOffsets( this, event );
440
+ }
441
+ }
442
+ }
443
+
444
+ this.dragDirection = {
445
+ vertical: this._getDragVerticalDirection(),
446
+ horizontal: this._getDragHorizontalDirection()
447
+ };
448
+
449
+ //Rearrange
450
+ for ( i = this.items.length - 1; i >= 0; i-- ) {
451
+
452
+ //Cache variables and intersection, continue if no intersection
453
+ item = this.items[ i ];
454
+ itemElement = item.item[ 0 ];
455
+ intersection = this._intersectsWithPointer( item );
456
+ if ( !intersection ) {
457
+ continue;
458
+ }
459
+
460
+ // Only put the placeholder inside the current Container, skip all
461
+ // items from other containers. This works because when moving
462
+ // an item from one container to another the
463
+ // currentContainer is switched before the placeholder is moved.
464
+ //
465
+ // Without this, moving items in "sub-sortables" can cause
466
+ // the placeholder to jitter between the outer and inner container.
467
+ if ( item.instance !== this.currentContainer ) {
468
+ continue;
469
+ }
470
+
471
+ // Cannot intersect with itself
472
+ // no useless actions that have been done before
473
+ // no action if the item moved is the parent of the item checked
474
+ if ( itemElement !== this.currentItem[ 0 ] &&
475
+ this.placeholder[ intersection === 1 ?
476
+ "next" : "prev" ]()[ 0 ] !== itemElement &&
477
+ !$.contains( this.placeholder[ 0 ], itemElement ) &&
478
+ ( this.options.type === "semi-dynamic" ?
479
+ !$.contains( this.element[ 0 ], itemElement ) :
480
+ true
481
+ )
482
+ ) {
483
+
484
+ this.direction = intersection === 1 ? "down" : "up";
485
+
486
+ if ( this.options.tolerance === "pointer" ||
487
+ this._intersectsWithSides( item ) ) {
488
+ this._rearrange( event, item );
489
+ } else {
490
+ break;
491
+ }
492
+
493
+ this._trigger( "change", event, this._uiHash() );
494
+ break;
495
+ }
496
+ }
497
+
498
+ //Post events to containers
499
+ this._contactContainers( event );
500
+
501
+ //Interconnect with droppables
502
+ if ( $.ui.ddmanager ) {
503
+ $.ui.ddmanager.drag( this, event );
504
+ }
505
+
506
+ //Call callbacks
507
+ this._trigger( "sort", event, this._uiHash() );
508
+
509
+ this.lastPositionAbs = this.positionAbs;
510
+ return false;
511
+
512
+ },
513
+
514
+ _mouseStop: function( event, noPropagation ) {
515
+
516
+ if ( !event ) {
517
+ return;
518
+ }
519
+
520
+ //If we are using droppables, inform the manager about the drop
521
+ if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
522
+ $.ui.ddmanager.drop( this, event );
523
+ }
524
+
525
+ if ( this.options.revert ) {
526
+ var that = this,
527
+ cur = this.placeholder.offset(),
528
+ axis = this.options.axis,
529
+ animation = {};
530
+
531
+ if ( !axis || axis === "x" ) {
532
+ animation.left = cur.left - this.offset.parent.left - this.margins.left +
533
+ ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
534
+ 0 :
535
+ this.offsetParent[ 0 ].scrollLeft
536
+ );
537
+ }
538
+ if ( !axis || axis === "y" ) {
539
+ animation.top = cur.top - this.offset.parent.top - this.margins.top +
540
+ ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
541
+ 0 :
542
+ this.offsetParent[ 0 ].scrollTop
543
+ );
544
+ }
545
+ this.reverting = true;
546
+ $( this.helper ).animate(
547
+ animation,
548
+ parseInt( this.options.revert, 10 ) || 500,
549
+ function() {
550
+ that._clear( event );
551
+ }
552
+ );
553
+ } else {
554
+ this._clear( event, noPropagation );
555
+ }
556
+
557
+ return false;
558
+
559
+ },
560
+
561
+ cancel: function() {
562
+
563
+ if ( this.dragging ) {
564
+
565
+ this._mouseUp( new $.Event( "mouseup", { target: null } ) );
566
+
567
+ if ( this.options.helper === "original" ) {
568
+ this.currentItem.css( this._storedCSS );
569
+ this._removeClass( this.currentItem, "ui-sortable-helper" );
570
+ } else {
571
+ this.currentItem.show();
572
+ }
573
+
574
+ //Post deactivating events to containers
575
+ for ( var i = this.containers.length - 1; i >= 0; i-- ) {
576
+ this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
577
+ if ( this.containers[ i ].containerCache.over ) {
578
+ this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
579
+ this.containers[ i ].containerCache.over = 0;
580
+ }
581
+ }
582
+
583
+ }
584
+
585
+ if ( this.placeholder ) {
586
+
587
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
588
+ // it unbinds ALL events from the original node!
589
+ if ( this.placeholder[ 0 ].parentNode ) {
590
+ this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
591
+ }
592
+ if ( this.options.helper !== "original" && this.helper &&
593
+ this.helper[ 0 ].parentNode ) {
594
+ this.helper.remove();
595
+ }
596
+
597
+ $.extend( this, {
598
+ helper: null,
599
+ dragging: false,
600
+ reverting: false,
601
+ _noFinalSort: null
602
+ } );
603
+
604
+ if ( this.domPosition.prev ) {
605
+ $( this.domPosition.prev ).after( this.currentItem );
606
+ } else {
607
+ $( this.domPosition.parent ).prepend( this.currentItem );
608
+ }
609
+ }
610
+
611
+ return this;
612
+
613
+ },
614
+
615
+ serialize: function( o ) {
616
+
617
+ var items = this._getItemsAsjQuery( o && o.connected ),
618
+ str = [];
619
+ o = o || {};
620
+
621
+ $( items ).each( function() {
622
+ var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
623
+ .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
624
+ if ( res ) {
625
+ str.push(
626
+ ( o.key || res[ 1 ] + "[]" ) +
627
+ "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
628
+ }
629
+ } );
630
+
631
+ if ( !str.length && o.key ) {
632
+ str.push( o.key + "=" );
633
+ }
634
+
635
+ return str.join( "&" );
636
+
637
+ },
638
+
639
+ toArray: function( o ) {
640
+
641
+ var items = this._getItemsAsjQuery( o && o.connected ),
642
+ ret = [];
643
+
644
+ o = o || {};
645
+
646
+ items.each( function() {
647
+ ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
648
+ } );
649
+ return ret;
650
+
651
+ },
652
+
653
+ /* Be careful with the following core functions */
654
+ _intersectsWith: function( item ) {
655
+
656
+ var x1 = this.positionAbs.left,
657
+ x2 = x1 + this.helperProportions.width,
658
+ y1 = this.positionAbs.top,
659
+ y2 = y1 + this.helperProportions.height,
660
+ l = item.left,
661
+ r = l + item.width,
662
+ t = item.top,
663
+ b = t + item.height,
664
+ dyClick = this.offset.click.top,
665
+ dxClick = this.offset.click.left,
666
+ isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
667
+ ( y1 + dyClick ) < b ),
668
+ isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
669
+ ( x1 + dxClick ) < r ),
670
+ isOverElement = isOverElementHeight && isOverElementWidth;
671
+
672
+ if ( this.options.tolerance === "pointer" ||
673
+ this.options.forcePointerForContainers ||
674
+ ( this.options.tolerance !== "pointer" &&
675
+ this.helperProportions[ this.floating ? "width" : "height" ] >
676
+ item[ this.floating ? "width" : "height" ] )
677
+ ) {
678
+ return isOverElement;
679
+ } else {
680
+
681
+ return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
682
+ x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
683
+ t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
684
+ y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
685
+
686
+ }
687
+ },
688
+
689
+ _intersectsWithPointer: function( item ) {
690
+ var verticalDirection, horizontalDirection,
691
+ isOverElementHeight = ( this.options.axis === "x" ) ||
692
+ this._isOverAxis(
693
+ this.positionAbs.top + this.offset.click.top, item.top, item.height ),
694
+ isOverElementWidth = ( this.options.axis === "y" ) ||
695
+ this._isOverAxis(
696
+ this.positionAbs.left + this.offset.click.left, item.left, item.width ),
697
+ isOverElement = isOverElementHeight && isOverElementWidth;
698
+
699
+ if ( !isOverElement ) {
700
+ return false;
701
+ }
702
+
703
+ verticalDirection = this.dragDirection.vertical;
704
+ horizontalDirection = this.dragDirection.horizontal;
705
+
706
+ return this.floating ?
707
+ ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
708
+ ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
709
+
710
+ },
711
+
712
+ _intersectsWithSides: function( item ) {
713
+
714
+ var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
715
+ this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
716
+ isOverRightHalf = this._isOverAxis( this.positionAbs.left +
717
+ this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
718
+ verticalDirection = this.dragDirection.vertical,
719
+ horizontalDirection = this.dragDirection.horizontal;
720
+
721
+ if ( this.floating && horizontalDirection ) {
722
+ return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
723
+ ( horizontalDirection === "left" && !isOverRightHalf ) );
724
+ } else {
725
+ return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
726
+ ( verticalDirection === "up" && !isOverBottomHalf ) );
727
+ }
728
+
729
+ },
730
+
731
+ _getDragVerticalDirection: function() {
732
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
733
+ return delta !== 0 && ( delta > 0 ? "down" : "up" );
734
+ },
735
+
736
+ _getDragHorizontalDirection: function() {
737
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
738
+ return delta !== 0 && ( delta > 0 ? "right" : "left" );
739
+ },
740
+
741
+ refresh: function( event ) {
742
+ this._refreshItems( event );
743
+ this._setHandleClassName();
744
+ this.refreshPositions();
745
+ return this;
746
+ },
747
+
748
+ _connectWith: function() {
749
+ var options = this.options;
750
+ return options.connectWith.constructor === String ?
751
+ [ options.connectWith ] :
752
+ options.connectWith;
753
+ },
754
+
755
+ _getItemsAsjQuery: function( connected ) {
756
+
757
+ var i, j, cur, inst,
758
+ items = [],
759
+ queries = [],
760
+ connectWith = this._connectWith();
761
+
762
+ if ( connectWith && connected ) {
763
+ for ( i = connectWith.length - 1; i >= 0; i-- ) {
764
+ cur = $( connectWith[ i ], this.document[ 0 ] );
765
+ for ( j = cur.length - 1; j >= 0; j-- ) {
766
+ inst = $.data( cur[ j ], this.widgetFullName );
767
+ if ( inst && inst !== this && !inst.options.disabled ) {
768
+ queries.push( [ typeof inst.options.items === "function" ?
769
+ inst.options.items.call( inst.element ) :
770
+ $( inst.options.items, inst.element )
771
+ .not( ".ui-sortable-helper" )
772
+ .not( ".ui-sortable-placeholder" ), inst ] );
773
+ }
774
+ }
775
+ }
776
+ }
777
+
778
+ queries.push( [ typeof this.options.items === "function" ?
779
+ this.options.items
780
+ .call( this.element, null, { options: this.options, item: this.currentItem } ) :
781
+ $( this.options.items, this.element )
782
+ .not( ".ui-sortable-helper" )
783
+ .not( ".ui-sortable-placeholder" ), this ] );
784
+
785
+ function addItems() {
786
+ items.push( this );
787
+ }
788
+ for ( i = queries.length - 1; i >= 0; i-- ) {
789
+ queries[ i ][ 0 ].each( addItems );
790
+ }
791
+
792
+ return $( items );
793
+
794
+ },
795
+
796
+ _removeCurrentsFromItems: function() {
797
+
798
+ var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
799
+
800
+ this.items = $.grep( this.items, function( item ) {
801
+ for ( var j = 0; j < list.length; j++ ) {
802
+ if ( list[ j ] === item.item[ 0 ] ) {
803
+ return false;
804
+ }
805
+ }
806
+ return true;
807
+ } );
808
+
809
+ },
810
+
811
+ _refreshItems: function( event ) {
812
+
813
+ this.items = [];
814
+ this.containers = [ this ];
815
+
816
+ var i, j, cur, inst, targetData, _queries, item, queriesLength,
817
+ items = this.items,
818
+ queries = [ [ typeof this.options.items === "function" ?
819
+ this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
820
+ $( this.options.items, this.element ), this ] ],
821
+ connectWith = this._connectWith();
822
+
823
+ //Shouldn't be run the first time through due to massive slow-down
824
+ if ( connectWith && this.ready ) {
825
+ for ( i = connectWith.length - 1; i >= 0; i-- ) {
826
+ cur = $( connectWith[ i ], this.document[ 0 ] );
827
+ for ( j = cur.length - 1; j >= 0; j-- ) {
828
+ inst = $.data( cur[ j ], this.widgetFullName );
829
+ if ( inst && inst !== this && !inst.options.disabled ) {
830
+ queries.push( [ typeof inst.options.items === "function" ?
831
+ inst.options.items
832
+ .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
833
+ $( inst.options.items, inst.element ), inst ] );
834
+ this.containers.push( inst );
835
+ }
836
+ }
837
+ }
838
+ }
839
+
840
+ for ( i = queries.length - 1; i >= 0; i-- ) {
841
+ targetData = queries[ i ][ 1 ];
842
+ _queries = queries[ i ][ 0 ];
843
+
844
+ for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
845
+ item = $( _queries[ j ] );
846
+
847
+ // Data for target checking (mouse manager)
848
+ item.data( this.widgetName + "-item", targetData );
849
+
850
+ items.push( {
851
+ item: item,
852
+ instance: targetData,
853
+ width: 0, height: 0,
854
+ left: 0, top: 0
855
+ } );
856
+ }
857
+ }
858
+
859
+ },
860
+
861
+ _refreshItemPositions: function( fast ) {
862
+ var i, item, t, p;
863
+
864
+ for ( i = this.items.length - 1; i >= 0; i-- ) {
865
+ item = this.items[ i ];
866
+
867
+ //We ignore calculating positions of all connected containers when we're not over them
868
+ if ( this.currentContainer && item.instance !== this.currentContainer &&
869
+ item.item[ 0 ] !== this.currentItem[ 0 ] ) {
870
+ continue;
871
+ }
872
+
873
+ t = this.options.toleranceElement ?
874
+ $( this.options.toleranceElement, item.item ) :
875
+ item.item;
876
+
877
+ if ( !fast ) {
878
+ item.width = t.outerWidth();
879
+ item.height = t.outerHeight();
880
+ }
881
+
882
+ p = t.offset();
883
+ item.left = p.left;
884
+ item.top = p.top;
885
+ }
886
+ },
887
+
888
+ refreshPositions: function( fast ) {
889
+
890
+ // Determine whether items are being displayed horizontally
891
+ this.floating = this.items.length ?
892
+ this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
893
+ false;
894
+
895
+ // This has to be redone because due to the item being moved out/into the offsetParent,
896
+ // the offsetParent's position will change
897
+ if ( this.offsetParent && this.helper ) {
898
+ this.offset.parent = this._getParentOffset();
899
+ }
900
+
901
+ this._refreshItemPositions( fast );
902
+
903
+ var i, p;
904
+
905
+ if ( this.options.custom && this.options.custom.refreshContainers ) {
906
+ this.options.custom.refreshContainers.call( this );
907
+ } else {
908
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
909
+ p = this.containers[ i ].element.offset();
910
+ this.containers[ i ].containerCache.left = p.left;
911
+ this.containers[ i ].containerCache.top = p.top;
912
+ this.containers[ i ].containerCache.width =
913
+ this.containers[ i ].element.outerWidth();
914
+ this.containers[ i ].containerCache.height =
915
+ this.containers[ i ].element.outerHeight();
916
+ }
917
+ }
918
+
919
+ return this;
920
+ },
921
+
922
+ _createPlaceholder: function( that ) {
923
+ that = that || this;
924
+ var className, nodeName,
925
+ o = that.options;
926
+
927
+ if ( !o.placeholder || o.placeholder.constructor === String ) {
928
+ className = o.placeholder;
929
+ nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
930
+ o.placeholder = {
931
+ element: function() {
932
+
933
+ var element = $( "<" + nodeName + ">", that.document[ 0 ] );
934
+
935
+ that._addClass( element, "ui-sortable-placeholder",
936
+ className || that.currentItem[ 0 ].className )
937
+ ._removeClass( element, "ui-sortable-helper" );
938
+
939
+ if ( nodeName === "tbody" ) {
940
+ that._createTrPlaceholder(
941
+ that.currentItem.find( "tr" ).eq( 0 ),
942
+ $( "<tr>", that.document[ 0 ] ).appendTo( element )
943
+ );
944
+ } else if ( nodeName === "tr" ) {
945
+ that._createTrPlaceholder( that.currentItem, element );
946
+ } else if ( nodeName === "img" ) {
947
+ element.attr( "src", that.currentItem.attr( "src" ) );
948
+ }
949
+
950
+ if ( !className ) {
951
+ element.css( "visibility", "hidden" );
952
+ }
953
+
954
+ return element;
955
+ },
956
+ update: function( container, p ) {
957
+
958
+ // 1. If a className is set as 'placeholder option, we don't force sizes -
959
+ // the class is responsible for that
960
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
961
+ // class name is specified
962
+ if ( className && !o.forcePlaceholderSize ) {
963
+ return;
964
+ }
965
+
966
+ // If the element doesn't have a actual height or width by itself (without
967
+ // styles coming from a stylesheet), it receives the inline height and width
968
+ // from the dragged item. Or, if it's a tbody or tr, it's going to have a height
969
+ // anyway since we're populating them with <td>s above, but they're unlikely to
970
+ // be the correct height on their own if the row heights are dynamic, so we'll
971
+ // always assign the height of the dragged item given forcePlaceholderSize
972
+ // is true.
973
+ if ( !p.height() || ( o.forcePlaceholderSize &&
974
+ ( nodeName === "tbody" || nodeName === "tr" ) ) ) {
975
+ p.height(
976
+ that.currentItem.innerHeight() -
977
+ parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
978
+ parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
979
+ }
980
+ if ( !p.width() ) {
981
+ p.width(
982
+ that.currentItem.innerWidth() -
983
+ parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
984
+ parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
985
+ }
986
+ }
987
+ };
988
+ }
989
+
990
+ //Create the placeholder
991
+ that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
992
+
993
+ //Append it after the actual current item
994
+ that.currentItem.after( that.placeholder );
995
+
996
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
997
+ o.placeholder.update( that, that.placeholder );
998
+
999
+ },
1000
+
1001
+ _createTrPlaceholder: function( sourceTr, targetTr ) {
1002
+ var that = this;
1003
+
1004
+ sourceTr.children().each( function() {
1005
+ $( "<td>&#160;</td>", that.document[ 0 ] )
1006
+ .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
1007
+ .appendTo( targetTr );
1008
+ } );
1009
+ },
1010
+
1011
+ _contactContainers: function( event ) {
1012
+ var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
1013
+ floating, axis,
1014
+ innermostContainer = null,
1015
+ innermostIndex = null;
1016
+
1017
+ // Get innermost container that intersects with item
1018
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
1019
+
1020
+ // Never consider a container that's located within the item itself
1021
+ if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
1022
+ continue;
1023
+ }
1024
+
1025
+ if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
1026
+
1027
+ // If we've already found a container and it's more "inner" than this, then continue
1028
+ if ( innermostContainer &&
1029
+ $.contains(
1030
+ this.containers[ i ].element[ 0 ],
1031
+ innermostContainer.element[ 0 ] ) ) {
1032
+ continue;
1033
+ }
1034
+
1035
+ innermostContainer = this.containers[ i ];
1036
+ innermostIndex = i;
1037
+
1038
+ } else {
1039
+
1040
+ // container doesn't intersect. trigger "out" event if necessary
1041
+ if ( this.containers[ i ].containerCache.over ) {
1042
+ this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
1043
+ this.containers[ i ].containerCache.over = 0;
1044
+ }
1045
+ }
1046
+
1047
+ }
1048
+
1049
+ // If no intersecting containers found, return
1050
+ if ( !innermostContainer ) {
1051
+ return;
1052
+ }
1053
+
1054
+ // Move the item into the container if it's not there already
1055
+ if ( this.containers.length === 1 ) {
1056
+ if ( !this.containers[ innermostIndex ].containerCache.over ) {
1057
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
1058
+ this.containers[ innermostIndex ].containerCache.over = 1;
1059
+ }
1060
+ } else {
1061
+
1062
+ // When entering a new container, we will find the item with the least distance and
1063
+ // append our item near it
1064
+ dist = 10000;
1065
+ itemWithLeastDistance = null;
1066
+ floating = innermostContainer.floating || this._isFloating( this.currentItem );
1067
+ posProperty = floating ? "left" : "top";
1068
+ sizeProperty = floating ? "width" : "height";
1069
+ axis = floating ? "pageX" : "pageY";
1070
+
1071
+ for ( j = this.items.length - 1; j >= 0; j-- ) {
1072
+ if ( !$.contains(
1073
+ this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
1074
+ ) {
1075
+ continue;
1076
+ }
1077
+ if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
1078
+ continue;
1079
+ }
1080
+
1081
+ cur = this.items[ j ].item.offset()[ posProperty ];
1082
+ nearBottom = false;
1083
+ if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
1084
+ nearBottom = true;
1085
+ }
1086
+
1087
+ if ( Math.abs( event[ axis ] - cur ) < dist ) {
1088
+ dist = Math.abs( event[ axis ] - cur );
1089
+ itemWithLeastDistance = this.items[ j ];
1090
+ this.direction = nearBottom ? "up" : "down";
1091
+ }
1092
+ }
1093
+
1094
+ //Check if dropOnEmpty is enabled
1095
+ if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
1096
+ return;
1097
+ }
1098
+
1099
+ if ( this.currentContainer === this.containers[ innermostIndex ] ) {
1100
+ if ( !this.currentContainer.containerCache.over ) {
1101
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
1102
+ this.currentContainer.containerCache.over = 1;
1103
+ }
1104
+ return;
1105
+ }
1106
+
1107
+ if ( itemWithLeastDistance ) {
1108
+ this._rearrange( event, itemWithLeastDistance, null, true );
1109
+ } else {
1110
+ this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
1111
+ }
1112
+ this._trigger( "change", event, this._uiHash() );
1113
+ this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
1114
+ this.currentContainer = this.containers[ innermostIndex ];
1115
+
1116
+ //Update the placeholder
1117
+ this.options.placeholder.update( this.currentContainer, this.placeholder );
1118
+
1119
+ //Update scrollParent
1120
+ this.scrollParent = this.placeholder.scrollParent();
1121
+
1122
+ //Update overflowOffset
1123
+ if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
1124
+ this.scrollParent[ 0 ].tagName !== "HTML" ) {
1125
+ this.overflowOffset = this.scrollParent.offset();
1126
+ }
1127
+
1128
+ this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
1129
+ this.containers[ innermostIndex ].containerCache.over = 1;
1130
+ }
1131
+
1132
+ },
1133
+
1134
+ _createHelper: function( event ) {
1135
+
1136
+ var o = this.options,
1137
+ helper = typeof o.helper === "function" ?
1138
+ $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
1139
+ ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
1140
+
1141
+ //Add the helper to the DOM if that didn't happen already
1142
+ if ( !helper.parents( "body" ).length ) {
1143
+ this.appendTo[ 0 ].appendChild( helper[ 0 ] );
1144
+ }
1145
+
1146
+ if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
1147
+ this._storedCSS = {
1148
+ width: this.currentItem[ 0 ].style.width,
1149
+ height: this.currentItem[ 0 ].style.height,
1150
+ position: this.currentItem.css( "position" ),
1151
+ top: this.currentItem.css( "top" ),
1152
+ left: this.currentItem.css( "left" )
1153
+ };
1154
+ }
1155
+
1156
+ if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
1157
+ helper.width( this.currentItem.width() );
1158
+ }
1159
+ if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
1160
+ helper.height( this.currentItem.height() );
1161
+ }
1162
+
1163
+ return helper;
1164
+
1165
+ },
1166
+
1167
+ _adjustOffsetFromHelper: function( obj ) {
1168
+ if ( typeof obj === "string" ) {
1169
+ obj = obj.split( " " );
1170
+ }
1171
+ if ( Array.isArray( obj ) ) {
1172
+ obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
1173
+ }
1174
+ if ( "left" in obj ) {
1175
+ this.offset.click.left = obj.left + this.margins.left;
1176
+ }
1177
+ if ( "right" in obj ) {
1178
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1179
+ }
1180
+ if ( "top" in obj ) {
1181
+ this.offset.click.top = obj.top + this.margins.top;
1182
+ }
1183
+ if ( "bottom" in obj ) {
1184
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1185
+ }
1186
+ },
1187
+
1188
+ _getParentOffset: function() {
1189
+
1190
+ //Get the offsetParent and cache its position
1191
+ this.offsetParent = this.helper.offsetParent();
1192
+ var po = this.offsetParent.offset();
1193
+
1194
+ // This is a special case where we need to modify a offset calculated on start, since the
1195
+ // following happened:
1196
+ // 1. The position of the helper is absolute, so it's position is calculated based on the
1197
+ // next positioned parent
1198
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
1199
+ // the document, which means that the scroll is included in the initial calculation of the
1200
+ // offset of the parent, and never recalculated upon drag
1201
+ if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
1202
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
1203
+ po.left += this.scrollParent.scrollLeft();
1204
+ po.top += this.scrollParent.scrollTop();
1205
+ }
1206
+
1207
+ // This needs to be actually done for all browsers, since pageX/pageY includes this
1208
+ // information with an ugly IE fix
1209
+ if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
1210
+ ( this.offsetParent[ 0 ].tagName &&
1211
+ this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
1212
+ po = { top: 0, left: 0 };
1213
+ }
1214
+
1215
+ return {
1216
+ top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
1217
+ left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
1218
+ };
1219
+
1220
+ },
1221
+
1222
+ _getRelativeOffset: function() {
1223
+
1224
+ if ( this.cssPosition === "relative" ) {
1225
+ var p = this.currentItem.position();
1226
+ return {
1227
+ top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
1228
+ this.scrollParent.scrollTop(),
1229
+ left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
1230
+ this.scrollParent.scrollLeft()
1231
+ };
1232
+ } else {
1233
+ return { top: 0, left: 0 };
1234
+ }
1235
+
1236
+ },
1237
+
1238
+ _cacheMargins: function() {
1239
+ this.margins = {
1240
+ left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
1241
+ top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
1242
+ };
1243
+ },
1244
+
1245
+ _cacheHelperProportions: function() {
1246
+ this.helperProportions = {
1247
+ width: this.helper.outerWidth(),
1248
+ height: this.helper.outerHeight()
1249
+ };
1250
+ },
1251
+
1252
+ _setContainment: function() {
1253
+
1254
+ var ce, co, over,
1255
+ o = this.options;
1256
+ if ( o.containment === "parent" ) {
1257
+ o.containment = this.helper[ 0 ].parentNode;
1258
+ }
1259
+ if ( o.containment === "document" || o.containment === "window" ) {
1260
+ this.containment = [
1261
+ 0 - this.offset.relative.left - this.offset.parent.left,
1262
+ 0 - this.offset.relative.top - this.offset.parent.top,
1263
+ o.containment === "document" ?
1264
+ this.document.width() :
1265
+ this.window.width() - this.helperProportions.width - this.margins.left,
1266
+ ( o.containment === "document" ?
1267
+ ( this.document.height() || document.body.parentNode.scrollHeight ) :
1268
+ this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
1269
+ ) - this.helperProportions.height - this.margins.top
1270
+ ];
1271
+ }
1272
+
1273
+ if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
1274
+ ce = $( o.containment )[ 0 ];
1275
+ co = $( o.containment ).offset();
1276
+ over = ( $( ce ).css( "overflow" ) !== "hidden" );
1277
+
1278
+ this.containment = [
1279
+ co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
1280
+ ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
1281
+ co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
1282
+ ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
1283
+ co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
1284
+ ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
1285
+ ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
1286
+ this.helperProportions.width - this.margins.left,
1287
+ co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
1288
+ ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
1289
+ ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
1290
+ this.helperProportions.height - this.margins.top
1291
+ ];
1292
+ }
1293
+
1294
+ },
1295
+
1296
+ _convertPositionTo: function( d, pos ) {
1297
+
1298
+ if ( !pos ) {
1299
+ pos = this.position;
1300
+ }
1301
+ var mod = d === "absolute" ? 1 : -1,
1302
+ scroll = this.cssPosition === "absolute" &&
1303
+ !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
1304
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
1305
+ this.offsetParent :
1306
+ this.scrollParent,
1307
+ scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
1308
+
1309
+ return {
1310
+ top: (
1311
+
1312
+ // The absolute mouse position
1313
+ pos.top +
1314
+
1315
+ // Only for relative positioned nodes: Relative offset from element to offset parent
1316
+ this.offset.relative.top * mod +
1317
+
1318
+ // The offsetParent's offset without borders (offset + border)
1319
+ this.offset.parent.top * mod -
1320
+ ( ( this.cssPosition === "fixed" ?
1321
+ -this.scrollParent.scrollTop() :
1322
+ ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
1323
+ ),
1324
+ left: (
1325
+
1326
+ // The absolute mouse position
1327
+ pos.left +
1328
+
1329
+ // Only for relative positioned nodes: Relative offset from element to offset parent
1330
+ this.offset.relative.left * mod +
1331
+
1332
+ // The offsetParent's offset without borders (offset + border)
1333
+ this.offset.parent.left * mod -
1334
+ ( ( this.cssPosition === "fixed" ?
1335
+ -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
1336
+ scroll.scrollLeft() ) * mod )
1337
+ )
1338
+ };
1339
+
1340
+ },
1341
+
1342
+ _generatePosition: function( event ) {
1343
+
1344
+ var top, left,
1345
+ o = this.options,
1346
+ pageX = event.pageX,
1347
+ pageY = event.pageY,
1348
+ scroll = this.cssPosition === "absolute" &&
1349
+ !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
1350
+ $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
1351
+ this.offsetParent :
1352
+ this.scrollParent,
1353
+ scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
1354
+
1355
+ // This is another very weird special case that only happens for relative elements:
1356
+ // 1. If the css position is relative
1357
+ // 2. and the scroll parent is the document or similar to the offset parent
1358
+ // we have to refresh the relative offset during the scroll so there are no jumps
1359
+ if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
1360
+ this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
1361
+ this.offset.relative = this._getRelativeOffset();
1362
+ }
1363
+
1364
+ /*
1365
+ * - Position constraining -
1366
+ * Constrain the position to a mix of grid, containment.
1367
+ */
1368
+
1369
+ if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
1370
+
1371
+ if ( this.containment ) {
1372
+ if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
1373
+ pageX = this.containment[ 0 ] + this.offset.click.left;
1374
+ }
1375
+ if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
1376
+ pageY = this.containment[ 1 ] + this.offset.click.top;
1377
+ }
1378
+ if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
1379
+ pageX = this.containment[ 2 ] + this.offset.click.left;
1380
+ }
1381
+ if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
1382
+ pageY = this.containment[ 3 ] + this.offset.click.top;
1383
+ }
1384
+ }
1385
+
1386
+ if ( o.grid ) {
1387
+ top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
1388
+ o.grid[ 1 ] ) * o.grid[ 1 ];
1389
+ pageY = this.containment ?
1390
+ ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
1391
+ top - this.offset.click.top <= this.containment[ 3 ] ) ?
1392
+ top :
1393
+ ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
1394
+ top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
1395
+ top;
1396
+
1397
+ left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
1398
+ o.grid[ 0 ] ) * o.grid[ 0 ];
1399
+ pageX = this.containment ?
1400
+ ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
1401
+ left - this.offset.click.left <= this.containment[ 2 ] ) ?
1402
+ left :
1403
+ ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
1404
+ left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
1405
+ left;
1406
+ }
1407
+
1408
+ }
1409
+
1410
+ return {
1411
+ top: (
1412
+
1413
+ // The absolute mouse position
1414
+ pageY -
1415
+
1416
+ // Click offset (relative to the element)
1417
+ this.offset.click.top -
1418
+
1419
+ // Only for relative positioned nodes: Relative offset from element to offset parent
1420
+ this.offset.relative.top -
1421
+
1422
+ // The offsetParent's offset without borders (offset + border)
1423
+ this.offset.parent.top +
1424
+ ( ( this.cssPosition === "fixed" ?
1425
+ -this.scrollParent.scrollTop() :
1426
+ ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
1427
+ ),
1428
+ left: (
1429
+
1430
+ // The absolute mouse position
1431
+ pageX -
1432
+
1433
+ // Click offset (relative to the element)
1434
+ this.offset.click.left -
1435
+
1436
+ // Only for relative positioned nodes: Relative offset from element to offset parent
1437
+ this.offset.relative.left -
1438
+
1439
+ // The offsetParent's offset without borders (offset + border)
1440
+ this.offset.parent.left +
1441
+ ( ( this.cssPosition === "fixed" ?
1442
+ -this.scrollParent.scrollLeft() :
1443
+ scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
1444
+ )
1445
+ };
1446
+
1447
+ },
1448
+
1449
+ _rearrange: function( event, i, a, hardRefresh ) {
1450
+
1451
+ if ( a ) {
1452
+ a[ 0 ].appendChild( this.placeholder[ 0 ] );
1453
+ } else {
1454
+ i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
1455
+ ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
1456
+ }
1457
+
1458
+ //Various things done here to improve the performance:
1459
+ // 1. we create a setTimeout, that calls refreshPositions
1460
+ // 2. on the instance, we have a counter variable, that get's higher after every append
1461
+ // 3. on the local scope, we copy the counter variable, and check in the timeout,
1462
+ // if it's still the same
1463
+ // 4. this lets only the last addition to the timeout stack through
1464
+ this.counter = this.counter ? ++this.counter : 1;
1465
+ var counter = this.counter;
1466
+
1467
+ this._delay( function() {
1468
+ if ( counter === this.counter ) {
1469
+
1470
+ //Precompute after each DOM insertion, NOT on mousemove
1471
+ this.refreshPositions( !hardRefresh );
1472
+ }
1473
+ } );
1474
+
1475
+ },
1476
+
1477
+ _clear: function( event, noPropagation ) {
1478
+
1479
+ this.reverting = false;
1480
+
1481
+ // We delay all events that have to be triggered to after the point where the placeholder
1482
+ // has been removed and everything else normalized again
1483
+ var i,
1484
+ delayedTriggers = [];
1485
+
1486
+ // We first have to update the dom position of the actual currentItem
1487
+ // Note: don't do it if the current item is already removed (by a user), or it gets
1488
+ // reappended (see #4088)
1489
+ if ( !this._noFinalSort && this.currentItem.parent().length ) {
1490
+ this.placeholder.before( this.currentItem );
1491
+ }
1492
+ this._noFinalSort = null;
1493
+
1494
+ if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
1495
+ for ( i in this._storedCSS ) {
1496
+ if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
1497
+ this._storedCSS[ i ] = "";
1498
+ }
1499
+ }
1500
+ this.currentItem.css( this._storedCSS );
1501
+ this._removeClass( this.currentItem, "ui-sortable-helper" );
1502
+ } else {
1503
+ this.currentItem.show();
1504
+ }
1505
+
1506
+ if ( this.fromOutside && !noPropagation ) {
1507
+ delayedTriggers.push( function( event ) {
1508
+ this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
1509
+ } );
1510
+ }
1511
+ if ( ( this.fromOutside ||
1512
+ this.domPosition.prev !==
1513
+ this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
1514
+ this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
1515
+
1516
+ // Trigger update callback if the DOM position has changed
1517
+ delayedTriggers.push( function( event ) {
1518
+ this._trigger( "update", event, this._uiHash() );
1519
+ } );
1520
+ }
1521
+
1522
+ // Check if the items Container has Changed and trigger appropriate
1523
+ // events.
1524
+ if ( this !== this.currentContainer ) {
1525
+ if ( !noPropagation ) {
1526
+ delayedTriggers.push( function( event ) {
1527
+ this._trigger( "remove", event, this._uiHash() );
1528
+ } );
1529
+ delayedTriggers.push( ( function( c ) {
1530
+ return function( event ) {
1531
+ c._trigger( "receive", event, this._uiHash( this ) );
1532
+ };
1533
+ } ).call( this, this.currentContainer ) );
1534
+ delayedTriggers.push( ( function( c ) {
1535
+ return function( event ) {
1536
+ c._trigger( "update", event, this._uiHash( this ) );
1537
+ };
1538
+ } ).call( this, this.currentContainer ) );
1539
+ }
1540
+ }
1541
+
1542
+ //Post events to containers
1543
+ function delayEvent( type, instance, container ) {
1544
+ return function( event ) {
1545
+ container._trigger( type, event, instance._uiHash( instance ) );
1546
+ };
1547
+ }
1548
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
1549
+ if ( !noPropagation ) {
1550
+ delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
1551
+ }
1552
+ if ( this.containers[ i ].containerCache.over ) {
1553
+ delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
1554
+ this.containers[ i ].containerCache.over = 0;
1555
+ }
1556
+ }
1557
+
1558
+ //Do what was originally in plugins
1559
+ if ( this.storedCursor ) {
1560
+ this.document.find( "body" ).css( "cursor", this.storedCursor );
1561
+ this.storedStylesheet.remove();
1562
+ }
1563
+ if ( this._storedOpacity ) {
1564
+ this.helper.css( "opacity", this._storedOpacity );
1565
+ }
1566
+ if ( this._storedZIndex ) {
1567
+ this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
1568
+ }
1569
+
1570
+ this.dragging = false;
1571
+
1572
+ if ( !noPropagation ) {
1573
+ this._trigger( "beforeStop", event, this._uiHash() );
1574
+ }
1575
+
1576
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
1577
+ // it unbinds ALL events from the original node!
1578
+ this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
1579
+
1580
+ if ( !this.cancelHelperRemoval ) {
1581
+ if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
1582
+ this.helper.remove();
1583
+ }
1584
+ this.helper = null;
1585
+ }
1586
+
1587
+ if ( !noPropagation ) {
1588
+ for ( i = 0; i < delayedTriggers.length; i++ ) {
1589
+
1590
+ // Trigger all delayed events
1591
+ delayedTriggers[ i ].call( this, event );
1592
+ }
1593
+ this._trigger( "stop", event, this._uiHash() );
1594
+ }
1595
+
1596
+ this.fromOutside = false;
1597
+ return !this.cancelHelperRemoval;
1598
+
1599
+ },
1600
+
1601
+ _trigger: function() {
1602
+ if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
1603
+ this.cancel();
1604
+ }
1605
+ },
1606
+
1607
+ _uiHash: function( _inst ) {
1608
+ var inst = _inst || this;
1609
+ return {
1610
+ helper: inst.helper,
1611
+ placeholder: inst.placeholder || $( [] ),
1612
+ position: inst.position,
1613
+ originalPosition: inst.originalPosition,
1614
+ offset: inst.positionAbs,
1615
+ item: inst.currentItem,
1616
+ sender: _inst ? _inst.element : null
1617
+ };
1618
+ }
1619
+
1620
+ } );
1621
+
1622
+ } );