spiderfw 0.6.27 → 0.6.28

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