flms 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +3 -0
  3. data/Rakefile +33 -0
  4. data/app/assets/images/img/glyphicons-halflings-white.png +0 -0
  5. data/app/assets/images/img/glyphicons-halflings.png +0 -0
  6. data/app/assets/javascripts/flms/blocks/index.coffee +6 -0
  7. data/app/assets/javascripts/flms/bootstrap.js +6 -0
  8. data/app/assets/javascripts/flms/flms.js +17 -0
  9. data/app/assets/javascripts/flms/layout.coffee +8 -0
  10. data/app/assets/stylesheets/flms/blocks/index.sass +28 -0
  11. data/app/assets/stylesheets/flms/bootstrap.css +6159 -0
  12. data/app/assets/stylesheets/flms/flms.css +7 -0
  13. data/app/assets/stylesheets/flms/home.sass +30 -0
  14. data/app/assets/stylesheets/flms/layout.sass +19 -0
  15. data/app/assets/stylesheets/flms/login.sass +32 -0
  16. data/app/controllers/flms/admin_controller.rb +11 -0
  17. data/app/controllers/flms/application_controller.rb +4 -0
  18. data/app/controllers/flms/blocks_controller.rb +55 -0
  19. data/app/controllers/flms/dashboard_controller.rb +13 -0
  20. data/app/controllers/flms/pages_controller.rb +47 -0
  21. data/app/controllers/flms/sessions_controller.rb +16 -0
  22. data/app/controllers/flms/users_controller.rb +31 -0
  23. data/app/helpers/flms/application_helper.rb +4 -0
  24. data/app/models/flms/block.rb +10 -0
  25. data/app/models/flms/blocks_page.rb +8 -0
  26. data/app/models/flms/page.rb +14 -0
  27. data/app/models/flms/user.rb +10 -0
  28. data/app/views/flms/blocks/_form.html.haml +25 -0
  29. data/app/views/flms/blocks/edit.html.haml +3 -0
  30. data/app/views/flms/blocks/index.html.haml +41 -0
  31. data/app/views/flms/blocks/new.html.haml +2 -0
  32. data/app/views/flms/blocks/show.html.haml +1 -0
  33. data/app/views/flms/dashboard/index.html.haml +5 -0
  34. data/app/views/flms/pages/_form.html.haml +30 -0
  35. data/app/views/flms/pages/edit.html.haml +3 -0
  36. data/app/views/flms/pages/index.html.haml +21 -0
  37. data/app/views/flms/pages/new.html.haml +2 -0
  38. data/app/views/flms/pages/show.html.haml +8 -0
  39. data/app/views/flms/sessions/new.html.haml +21 -0
  40. data/app/views/flms/users/_form.html.haml +28 -0
  41. data/app/views/flms/users/index.html.haml +22 -0
  42. data/app/views/flms/users/new.html.haml +3 -0
  43. data/app/views/layouts/flms/admin.html.haml +40 -0
  44. data/app/views/layouts/flms/admin_login.html.haml +18 -0
  45. data/app/views/layouts/flms/application.html.erb +14 -0
  46. data/config/initializers/devise.rb +243 -0
  47. data/config/locales/devise.en.yml +59 -0
  48. data/config/routes.rb +23 -0
  49. data/db/migrate/20130208224914_flms_devise_create_users.rb +47 -0
  50. data/db/migrate/20130216032241_flms_create_pages.rb +12 -0
  51. data/db/migrate/20130302011705_create_flms_blocks.rb +10 -0
  52. data/db/migrate/20130302015459_create_flms_blocks_pages.rb +12 -0
  53. data/lib/flms.rb +7 -0
  54. data/lib/flms/engine.rb +5 -0
  55. data/lib/flms/version.rb +3 -0
  56. data/lib/tasks/flms_tasks.rake +26 -0
  57. data/spec/controllers/blocks_controller_spec.rb +61 -0
  58. data/spec/controllers/dashboard_controller_spec.rb +12 -0
  59. data/spec/controllers/pages_controller_spec.rb +60 -0
  60. data/spec/controllers/users_controller_spec.rb +37 -0
  61. data/spec/dummy/Rakefile +7 -0
  62. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  63. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  64. data/spec/dummy/app/controllers/application_controller.rb +12 -0
  65. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  66. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  67. data/spec/dummy/app/models/user.rb +8 -0
  68. data/spec/dummy/app/views/home/index.html.haml +10 -0
  69. data/spec/dummy/app/views/layouts/application.html.haml +10 -0
  70. data/spec/dummy/config.ru +4 -0
  71. data/spec/dummy/config/application.rb +69 -0
  72. data/spec/dummy/config/boot.rb +10 -0
  73. data/spec/dummy/config/database.yml +52 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +37 -0
  76. data/spec/dummy/config/environments/production.rb +67 -0
  77. data/spec/dummy/config/environments/test.rb +37 -0
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/spec/dummy/config/initializers/devise.rb +244 -0
  80. data/spec/dummy/config/initializers/flms.rb +1 -0
  81. data/spec/dummy/config/initializers/inflections.rb +15 -0
  82. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  83. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  84. data/spec/dummy/config/initializers/session_store.rb +8 -0
  85. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  86. data/spec/dummy/config/locales/en.yml +5 -0
  87. data/spec/dummy/config/routes.rb +4 -0
  88. data/spec/dummy/db/schema.rb +60 -0
  89. data/spec/dummy/log/development.log +39893 -0
  90. data/spec/dummy/log/test.log +42855 -0
  91. data/spec/dummy/public/404.html +26 -0
  92. data/spec/dummy/public/422.html +26 -0
  93. data/spec/dummy/public/500.html +25 -0
  94. data/spec/dummy/public/favicon.ico +0 -0
  95. data/spec/dummy/script/rails +6 -0
  96. data/spec/dummy/tmp/cache/assets/C9D/180/sprockets%2Fad74b633d2447502477133032afac84b +0 -0
  97. data/spec/dummy/tmp/cache/assets/CAB/C80/sprockets%2Fc4e739111d82c7189113aeb228816ba8 +0 -0
  98. data/spec/dummy/tmp/cache/assets/CB9/E30/sprockets%2F588cf5763c29e490d026f24e8aa90343 +0 -0
  99. data/spec/dummy/tmp/cache/assets/CCF/210/sprockets%2F43b5c2ffc8a62726b4ed6234001571a4 +0 -0
  100. data/spec/dummy/tmp/cache/assets/CDB/510/sprockets%2Fd61745a24c4636f8813fa14038bac69a +0 -0
  101. data/spec/dummy/tmp/cache/assets/CDE/D90/sprockets%2Fcc733e310d9646637216c4ffe109ea35 +0 -0
  102. data/spec/dummy/tmp/cache/assets/CE4/6B0/sprockets%2F6e38aec803936176be248f507eb3432d +0 -0
  103. data/spec/dummy/tmp/cache/assets/CED/6A0/sprockets%2Fcc221f5201d658cf456836f8b5547f9d +0 -0
  104. data/spec/dummy/tmp/cache/assets/CF6/740/sprockets%2F0cb88349ae46593e396c4bd68854ed08 +0 -0
  105. data/spec/dummy/tmp/cache/assets/D01/E80/sprockets%2Fc1a3694915166d6a041afa4bb062fd84 +0 -0
  106. data/spec/dummy/tmp/cache/assets/D06/AF0/sprockets%2F02a9a4f214368781ba86ed42d5bef203 +0 -0
  107. data/spec/dummy/tmp/cache/assets/D07/250/sprockets%2Fa8bf27de087b582dc454910a060e0b84 +0 -0
  108. data/spec/dummy/tmp/cache/assets/D09/5C0/sprockets%2F7cd3521c63623eb6f02dbb514991a6f6 +0 -0
  109. data/spec/dummy/tmp/cache/assets/D0C/570/sprockets%2F7e3d63e1412ae56b44b23d95547f0cc7 +0 -0
  110. data/spec/dummy/tmp/cache/assets/D0D/510/sprockets%2Fa189f1a8718ff11152feb3c43c75b841 +0 -0
  111. data/spec/dummy/tmp/cache/assets/D1A/3F0/sprockets%2F84181c4b293f3a1c4efe9226652f9e6e +0 -0
  112. data/spec/dummy/tmp/cache/assets/D1E/1D0/sprockets%2Ffeec495723d877b92c74db2055516bc9 +0 -0
  113. data/spec/dummy/tmp/cache/assets/D2E/F10/sprockets%2F156bfd6b405a129f5f003243cf60aea9 +0 -0
  114. data/spec/dummy/tmp/cache/assets/D35/470/sprockets%2F2c0a647ea89470a8285b9acb2006dbd5 +0 -0
  115. data/spec/dummy/tmp/cache/assets/D3B/440/sprockets%2Fabe31f236167ba051f6ff849d0a7282f +0 -0
  116. data/spec/dummy/tmp/cache/assets/D3B/550/sprockets%2Fb61caf9834ac8c31691851ac024f26ef +0 -0
  117. data/spec/dummy/tmp/cache/assets/D44/A50/sprockets%2F7602cd388554ba54eb914c1b2d7ff68c +0 -0
  118. data/spec/dummy/tmp/cache/assets/D46/210/sprockets%2F45a8d49c8edbaf91f38ab1495430384c +0 -0
  119. data/spec/dummy/tmp/cache/assets/D4A/B40/sprockets%2F509d2dc1350975d781c50dffc58ef53f +0 -0
  120. data/spec/dummy/tmp/cache/assets/D54/DE0/sprockets%2F77af3e306bb966f71f83e90e2a8868db +0 -0
  121. data/spec/dummy/tmp/cache/assets/D5B/1F0/sprockets%2F4d98e747aa4bb9fc8859f49a45159e1c +0 -0
  122. data/spec/dummy/tmp/cache/assets/D65/690/sprockets%2F511f71e32f87da06df67250bb39abdc2 +0 -0
  123. data/spec/dummy/tmp/cache/assets/D6E/870/sprockets%2F3f77e0b5396013fd145a6fdd21bc9b7f +0 -0
  124. data/spec/dummy/tmp/cache/assets/D74/EA0/sprockets%2Fccfc557971c4d47336cab75db207b89a +0 -0
  125. data/spec/dummy/tmp/cache/assets/D77/D80/sprockets%2F7ad794c63274a9812dfbabc1dae69692 +0 -0
  126. data/spec/dummy/tmp/cache/assets/D79/DE0/sprockets%2F9e7131d002f39be972e9918bdfbbcc66 +0 -0
  127. data/spec/dummy/tmp/cache/assets/D7C/3A0/sprockets%2Fec63717067efd6b2daf3423edf70f689 +0 -0
  128. data/spec/dummy/tmp/cache/assets/D81/300/sprockets%2F9543b0420abb11b0a126a8384edddafe +0 -0
  129. data/spec/dummy/tmp/cache/assets/D81/400/sprockets%2F566656e2cc9e698b1dbbd56d6e2e6b36 +0 -0
  130. data/spec/dummy/tmp/cache/assets/D93/0C0/sprockets%2Fab900c084c9c51c312ee3457cee8cdc2 +0 -0
  131. data/spec/dummy/tmp/cache/assets/D98/FD0/sprockets%2F6f253bd2bf824ac38c69bfe1418a04be +0 -0
  132. data/spec/dummy/tmp/cache/assets/D9E/220/sprockets%2Fd129fcf804e89814c2f4abbe0336cba9 +0 -0
  133. data/spec/dummy/tmp/cache/assets/DA0/9F0/sprockets%2Fd7c0d94bf0df6b0e03f83dcaf8873631 +0 -0
  134. data/spec/dummy/tmp/cache/assets/DA3/920/sprockets%2F6c45b9f8e0152c78b3c9be1c2e8be53c +0 -0
  135. data/spec/dummy/tmp/cache/assets/DA5/BC0/sprockets%2F5b86068a872e5bd841750d6cbd2dfdbf +0 -0
  136. data/spec/dummy/tmp/cache/assets/DA8/4A0/sprockets%2Ff8ba39d58ace11df624bf7e24c7b5882 +0 -0
  137. data/spec/dummy/tmp/cache/assets/DA8/C30/sprockets%2Fb7d14d588a70a56d7ddac542eef557d6 +0 -0
  138. data/spec/dummy/tmp/cache/assets/DA9/370/sprockets%2Fdf257d496b11ea9c1bb7ee139d68c83e +0 -0
  139. data/spec/dummy/tmp/cache/assets/DAC/D80/sprockets%2Fb8ca14c15e0301b935aaaef327bdc40a +0 -0
  140. data/spec/dummy/tmp/cache/assets/DAE/F10/sprockets%2F46950fdbeed95ba83ca8e7215194ddf8 +0 -0
  141. data/spec/dummy/tmp/cache/assets/DB2/1F0/sprockets%2F9fe57997f92efbee3b03df4510a2df57 +0 -0
  142. data/spec/dummy/tmp/cache/assets/DB8/C30/sprockets%2Fca860af2d10e0c745b6e38b12dabe05f +0 -0
  143. data/spec/dummy/tmp/cache/assets/DC1/530/sprockets%2F4db0b289eee7dad03453a5924c20dcfa +0 -0
  144. data/spec/dummy/tmp/cache/assets/DC6/7D0/sprockets%2Ff7689ac5fafbf683c537892e6ff7f8c3 +0 -0
  145. data/spec/dummy/tmp/cache/assets/DCC/B80/sprockets%2Fb7ae6e7bfa8984c54a4dfaf0011617cd +0 -0
  146. data/spec/dummy/tmp/cache/assets/DCE/790/sprockets%2Fff77d67febbb3af024f721c0bb4c4749 +0 -0
  147. data/spec/dummy/tmp/cache/assets/DCF/0B0/sprockets%2F23db7ab96a5549546bbdd0bc2e6ea86f +0 -0
  148. data/spec/dummy/tmp/cache/assets/DD5/440/sprockets%2F9b3488ba6d62c3dcc809f8cd3dc2d1f5 +0 -0
  149. data/spec/dummy/tmp/cache/assets/DE6/B10/sprockets%2Fa0adf3fb2b0054d04dd44c08aff1d6c8 +0 -0
  150. data/spec/dummy/tmp/cache/assets/DF1/A10/sprockets%2Fa925a815ca0bff4d6f42fbdf0d323a4f +0 -0
  151. data/spec/dummy/tmp/cache/assets/DFA/FF0/sprockets%2F75699fed9ddaecd89464492eeeef90d8 +0 -0
  152. data/spec/dummy/tmp/cache/assets/DFD/540/sprockets%2F181ef7a7c275dd2872aa1ed1fcfab75f +0 -0
  153. data/spec/dummy/tmp/cache/assets/E0E/B50/sprockets%2Fe78fa5fc4cfb0979876d23ae1b1f3ffd +0 -0
  154. data/spec/dummy/tmp/cache/assets/E3A/110/sprockets%2Fb6d5158ff7ac6d2ca99bfe56a7ddd2e3 +0 -0
  155. data/spec/dummy/tmp/cache/assets/E6D/8B0/sprockets%2F9edfdf7e85cdd1a69b0eb14c6ce8ed19 +0 -0
  156. data/spec/factories/blocks.rb +6 -0
  157. data/spec/factories/pages.rb +6 -0
  158. data/spec/factories/users.rb +7 -0
  159. data/spec/features/blocks/create_spec.rb +19 -0
  160. data/spec/features/blocks/delete_spec.rb +17 -0
  161. data/spec/features/blocks/edit_spec.rb +20 -0
  162. data/spec/features/blocks/show_spec.rb +14 -0
  163. data/spec/features/dashboard_spec.rb +11 -0
  164. data/spec/features/login_spec.rb +50 -0
  165. data/spec/features/pages/create_spec.rb +18 -0
  166. data/spec/features/pages/delete_spec.rb +14 -0
  167. data/spec/features/pages/index_spec.rb +14 -0
  168. data/spec/features/pages/update_spec.rb +17 -0
  169. data/spec/features/users/create_spec.rb +20 -0
  170. data/spec/features/users/delete_spec.rb +13 -0
  171. data/spec/features/users/index_spec.rb +16 -0
  172. data/spec/flms_spec.rb +7 -0
  173. data/spec/models/block_spec.rb +14 -0
  174. data/spec/models/page_spec.rb +15 -0
  175. data/spec/models/user_spec.rb +5 -0
  176. data/spec/spec_helper.rb +53 -0
  177. data/spec/support/access_control.rb +87 -0
  178. data/spec/support/capybara_helpers.rb +7 -0
  179. data/spec/support/lets.rb +8 -0
  180. data/vendor/assets/javascripts/bootstrapSwitch.js +238 -0
  181. data/vendor/assets/javascripts/jquery-ui.js +2221 -0
  182. data/vendor/assets/stylesheets/bootstrapSwitch.css +210 -0
  183. data/vendor/assets/stylesheets/jquery-ui.css +88 -0
  184. metadata +607 -0
@@ -0,0 +1,2221 @@
1
+ /*! jQuery UI - v1.10.1 - 2013-03-05
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.sortable.js
4
+ * Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
5
+
6
+ (function( $, undefined ) {
7
+
8
+ var uuid = 0,
9
+ runiqueId = /^ui-id-\d+$/;
10
+
11
+ // prevent duplicate loading
12
+ // this is only a problem because we proxy existing functions
13
+ // and we don't want to double proxy them
14
+ $.ui = $.ui || {};
15
+ if ( $.ui.version ) {
16
+ return;
17
+ }
18
+
19
+ $.extend( $.ui, {
20
+ version: "1.10.1",
21
+
22
+ keyCode: {
23
+ BACKSPACE: 8,
24
+ COMMA: 188,
25
+ DELETE: 46,
26
+ DOWN: 40,
27
+ END: 35,
28
+ ENTER: 13,
29
+ ESCAPE: 27,
30
+ HOME: 36,
31
+ LEFT: 37,
32
+ NUMPAD_ADD: 107,
33
+ NUMPAD_DECIMAL: 110,
34
+ NUMPAD_DIVIDE: 111,
35
+ NUMPAD_ENTER: 108,
36
+ NUMPAD_MULTIPLY: 106,
37
+ NUMPAD_SUBTRACT: 109,
38
+ PAGE_DOWN: 34,
39
+ PAGE_UP: 33,
40
+ PERIOD: 190,
41
+ RIGHT: 39,
42
+ SPACE: 32,
43
+ TAB: 9,
44
+ UP: 38
45
+ }
46
+ });
47
+
48
+ // plugins
49
+ $.fn.extend({
50
+ _focus: $.fn.focus,
51
+ focus: function( delay, fn ) {
52
+ return typeof delay === "number" ?
53
+ this.each(function() {
54
+ var elem = this;
55
+ setTimeout(function() {
56
+ $( elem ).focus();
57
+ if ( fn ) {
58
+ fn.call( elem );
59
+ }
60
+ }, delay );
61
+ }) :
62
+ this._focus.apply( this, arguments );
63
+ },
64
+
65
+ scrollParent: function() {
66
+ var scrollParent;
67
+ if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
68
+ scrollParent = this.parents().filter(function() {
69
+ return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70
+ }).eq(0);
71
+ } else {
72
+ scrollParent = this.parents().filter(function() {
73
+ return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
74
+ }).eq(0);
75
+ }
76
+
77
+ return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
78
+ },
79
+
80
+ zIndex: function( zIndex ) {
81
+ if ( zIndex !== undefined ) {
82
+ return this.css( "zIndex", zIndex );
83
+ }
84
+
85
+ if ( this.length ) {
86
+ var elem = $( this[ 0 ] ), position, value;
87
+ while ( elem.length && elem[ 0 ] !== document ) {
88
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
89
+ // This makes behavior of this function consistent across browsers
90
+ // WebKit always returns auto if the element is positioned
91
+ position = elem.css( "position" );
92
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
93
+ // IE returns 0 when zIndex is not specified
94
+ // other browsers return a string
95
+ // we ignore the case of nested elements with an explicit value of 0
96
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
97
+ value = parseInt( elem.css( "zIndex" ), 10 );
98
+ if ( !isNaN( value ) && value !== 0 ) {
99
+ return value;
100
+ }
101
+ }
102
+ elem = elem.parent();
103
+ }
104
+ }
105
+
106
+ return 0;
107
+ },
108
+
109
+ uniqueId: function() {
110
+ return this.each(function() {
111
+ if ( !this.id ) {
112
+ this.id = "ui-id-" + (++uuid);
113
+ }
114
+ });
115
+ },
116
+
117
+ removeUniqueId: function() {
118
+ return this.each(function() {
119
+ if ( runiqueId.test( this.id ) ) {
120
+ $( this ).removeAttr( "id" );
121
+ }
122
+ });
123
+ }
124
+ });
125
+
126
+ // selectors
127
+ function focusable( element, isTabIndexNotNaN ) {
128
+ var map, mapName, img,
129
+ nodeName = element.nodeName.toLowerCase();
130
+ if ( "area" === nodeName ) {
131
+ map = element.parentNode;
132
+ mapName = map.name;
133
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134
+ return false;
135
+ }
136
+ img = $( "img[usemap=#" + mapName + "]" )[0];
137
+ return !!img && visible( img );
138
+ }
139
+ return ( /input|select|textarea|button|object/.test( nodeName ) ?
140
+ !element.disabled :
141
+ "a" === nodeName ?
142
+ element.href || isTabIndexNotNaN :
143
+ isTabIndexNotNaN) &&
144
+ // the element and all of its ancestors must be visible
145
+ visible( element );
146
+ }
147
+
148
+ function visible( element ) {
149
+ return $.expr.filters.visible( element ) &&
150
+ !$( element ).parents().addBack().filter(function() {
151
+ return $.css( this, "visibility" ) === "hidden";
152
+ }).length;
153
+ }
154
+
155
+ $.extend( $.expr[ ":" ], {
156
+ data: $.expr.createPseudo ?
157
+ $.expr.createPseudo(function( dataName ) {
158
+ return function( elem ) {
159
+ return !!$.data( elem, dataName );
160
+ };
161
+ }) :
162
+ // support: jQuery <1.8
163
+ function( elem, i, match ) {
164
+ return !!$.data( elem, match[ 3 ] );
165
+ },
166
+
167
+ focusable: function( element ) {
168
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169
+ },
170
+
171
+ tabbable: function( element ) {
172
+ var tabIndex = $.attr( element, "tabindex" ),
173
+ isTabIndexNaN = isNaN( tabIndex );
174
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175
+ }
176
+ });
177
+
178
+ // support: jQuery <1.8
179
+ if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
180
+ $.each( [ "Width", "Height" ], function( i, name ) {
181
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
182
+ type = name.toLowerCase(),
183
+ orig = {
184
+ innerWidth: $.fn.innerWidth,
185
+ innerHeight: $.fn.innerHeight,
186
+ outerWidth: $.fn.outerWidth,
187
+ outerHeight: $.fn.outerHeight
188
+ };
189
+
190
+ function reduce( elem, size, border, margin ) {
191
+ $.each( side, function() {
192
+ size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
193
+ if ( border ) {
194
+ size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
195
+ }
196
+ if ( margin ) {
197
+ size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
198
+ }
199
+ });
200
+ return size;
201
+ }
202
+
203
+ $.fn[ "inner" + name ] = function( size ) {
204
+ if ( size === undefined ) {
205
+ return orig[ "inner" + name ].call( this );
206
+ }
207
+
208
+ return this.each(function() {
209
+ $( this ).css( type, reduce( this, size ) + "px" );
210
+ });
211
+ };
212
+
213
+ $.fn[ "outer" + name] = function( size, margin ) {
214
+ if ( typeof size !== "number" ) {
215
+ return orig[ "outer" + name ].call( this, size );
216
+ }
217
+
218
+ return this.each(function() {
219
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
220
+ });
221
+ };
222
+ });
223
+ }
224
+
225
+ // support: jQuery <1.8
226
+ if ( !$.fn.addBack ) {
227
+ $.fn.addBack = function( selector ) {
228
+ return this.add( selector == null ?
229
+ this.prevObject : this.prevObject.filter( selector )
230
+ );
231
+ };
232
+ }
233
+
234
+ // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
235
+ if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
236
+ $.fn.removeData = (function( removeData ) {
237
+ return function( key ) {
238
+ if ( arguments.length ) {
239
+ return removeData.call( this, $.camelCase( key ) );
240
+ } else {
241
+ return removeData.call( this );
242
+ }
243
+ };
244
+ })( $.fn.removeData );
245
+ }
246
+
247
+
248
+
249
+
250
+
251
+ // deprecated
252
+ $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
253
+
254
+ $.support.selectstart = "onselectstart" in document.createElement( "div" );
255
+ $.fn.extend({
256
+ disableSelection: function() {
257
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
258
+ ".ui-disableSelection", function( event ) {
259
+ event.preventDefault();
260
+ });
261
+ },
262
+
263
+ enableSelection: function() {
264
+ return this.unbind( ".ui-disableSelection" );
265
+ }
266
+ });
267
+
268
+ $.extend( $.ui, {
269
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
270
+ plugin: {
271
+ add: function( module, option, set ) {
272
+ var i,
273
+ proto = $.ui[ module ].prototype;
274
+ for ( i in set ) {
275
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
276
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
277
+ }
278
+ },
279
+ call: function( instance, name, args ) {
280
+ var i,
281
+ set = instance.plugins[ name ];
282
+ if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
283
+ return;
284
+ }
285
+
286
+ for ( i = 0; i < set.length; i++ ) {
287
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
288
+ set[ i ][ 1 ].apply( instance.element, args );
289
+ }
290
+ }
291
+ }
292
+ },
293
+
294
+ // only used by resizable
295
+ hasScroll: function( el, a ) {
296
+
297
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
298
+ if ( $( el ).css( "overflow" ) === "hidden") {
299
+ return false;
300
+ }
301
+
302
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
303
+ has = false;
304
+
305
+ if ( el[ scroll ] > 0 ) {
306
+ return true;
307
+ }
308
+
309
+ // TODO: determine which cases actually cause this to happen
310
+ // if the element doesn't have the scroll set, see if it's possible to
311
+ // set the scroll
312
+ el[ scroll ] = 1;
313
+ has = ( el[ scroll ] > 0 );
314
+ el[ scroll ] = 0;
315
+ return has;
316
+ }
317
+ });
318
+
319
+ })( jQuery );
320
+ (function( $, undefined ) {
321
+
322
+ var uuid = 0,
323
+ slice = Array.prototype.slice,
324
+ _cleanData = $.cleanData;
325
+ $.cleanData = function( elems ) {
326
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
327
+ try {
328
+ $( elem ).triggerHandler( "remove" );
329
+ // http://bugs.jquery.com/ticket/8235
330
+ } catch( e ) {}
331
+ }
332
+ _cleanData( elems );
333
+ };
334
+
335
+ $.widget = function( name, base, prototype ) {
336
+ var fullName, existingConstructor, constructor, basePrototype,
337
+ // proxiedPrototype allows the provided prototype to remain unmodified
338
+ // so that it can be used as a mixin for multiple widgets (#8876)
339
+ proxiedPrototype = {},
340
+ namespace = name.split( "." )[ 0 ];
341
+
342
+ name = name.split( "." )[ 1 ];
343
+ fullName = namespace + "-" + name;
344
+
345
+ if ( !prototype ) {
346
+ prototype = base;
347
+ base = $.Widget;
348
+ }
349
+
350
+ // create selector for plugin
351
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
352
+ return !!$.data( elem, fullName );
353
+ };
354
+
355
+ $[ namespace ] = $[ namespace ] || {};
356
+ existingConstructor = $[ namespace ][ name ];
357
+ constructor = $[ namespace ][ name ] = function( options, element ) {
358
+ // allow instantiation without "new" keyword
359
+ if ( !this._createWidget ) {
360
+ return new constructor( options, element );
361
+ }
362
+
363
+ // allow instantiation without initializing for simple inheritance
364
+ // must use "new" keyword (the code above always passes args)
365
+ if ( arguments.length ) {
366
+ this._createWidget( options, element );
367
+ }
368
+ };
369
+ // extend with the existing constructor to carry over any static properties
370
+ $.extend( constructor, existingConstructor, {
371
+ version: prototype.version,
372
+ // copy the object used to create the prototype in case we need to
373
+ // redefine the widget later
374
+ _proto: $.extend( {}, prototype ),
375
+ // track widgets that inherit from this widget in case this widget is
376
+ // redefined after a widget inherits from it
377
+ _childConstructors: []
378
+ });
379
+
380
+ basePrototype = new base();
381
+ // we need to make the options hash a property directly on the new instance
382
+ // otherwise we'll modify the options hash on the prototype that we're
383
+ // inheriting from
384
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
385
+ $.each( prototype, function( prop, value ) {
386
+ if ( !$.isFunction( value ) ) {
387
+ proxiedPrototype[ prop ] = value;
388
+ return;
389
+ }
390
+ proxiedPrototype[ prop ] = (function() {
391
+ var _super = function() {
392
+ return base.prototype[ prop ].apply( this, arguments );
393
+ },
394
+ _superApply = function( args ) {
395
+ return base.prototype[ prop ].apply( this, args );
396
+ };
397
+ return function() {
398
+ var __super = this._super,
399
+ __superApply = this._superApply,
400
+ returnValue;
401
+
402
+ this._super = _super;
403
+ this._superApply = _superApply;
404
+
405
+ returnValue = value.apply( this, arguments );
406
+
407
+ this._super = __super;
408
+ this._superApply = __superApply;
409
+
410
+ return returnValue;
411
+ };
412
+ })();
413
+ });
414
+ constructor.prototype = $.widget.extend( basePrototype, {
415
+ // TODO: remove support for widgetEventPrefix
416
+ // always use the name + a colon as the prefix, e.g., draggable:start
417
+ // don't prefix for widgets that aren't DOM-based
418
+ widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
419
+ }, proxiedPrototype, {
420
+ constructor: constructor,
421
+ namespace: namespace,
422
+ widgetName: name,
423
+ widgetFullName: fullName
424
+ });
425
+
426
+ // If this widget is being redefined then we need to find all widgets that
427
+ // are inheriting from it and redefine all of them so that they inherit from
428
+ // the new version of this widget. We're essentially trying to replace one
429
+ // level in the prototype chain.
430
+ if ( existingConstructor ) {
431
+ $.each( existingConstructor._childConstructors, function( i, child ) {
432
+ var childPrototype = child.prototype;
433
+
434
+ // redefine the child widget using the same prototype that was
435
+ // originally used, but inherit from the new version of the base
436
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
437
+ });
438
+ // remove the list of existing child constructors from the old constructor
439
+ // so the old child constructors can be garbage collected
440
+ delete existingConstructor._childConstructors;
441
+ } else {
442
+ base._childConstructors.push( constructor );
443
+ }
444
+
445
+ $.widget.bridge( name, constructor );
446
+ };
447
+
448
+ $.widget.extend = function( target ) {
449
+ var input = slice.call( arguments, 1 ),
450
+ inputIndex = 0,
451
+ inputLength = input.length,
452
+ key,
453
+ value;
454
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
455
+ for ( key in input[ inputIndex ] ) {
456
+ value = input[ inputIndex ][ key ];
457
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
458
+ // Clone objects
459
+ if ( $.isPlainObject( value ) ) {
460
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
461
+ $.widget.extend( {}, target[ key ], value ) :
462
+ // Don't extend strings, arrays, etc. with objects
463
+ $.widget.extend( {}, value );
464
+ // Copy everything else by reference
465
+ } else {
466
+ target[ key ] = value;
467
+ }
468
+ }
469
+ }
470
+ }
471
+ return target;
472
+ };
473
+
474
+ $.widget.bridge = function( name, object ) {
475
+ var fullName = object.prototype.widgetFullName || name;
476
+ $.fn[ name ] = function( options ) {
477
+ var isMethodCall = typeof options === "string",
478
+ args = slice.call( arguments, 1 ),
479
+ returnValue = this;
480
+
481
+ // allow multiple hashes to be passed on init
482
+ options = !isMethodCall && args.length ?
483
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
484
+ options;
485
+
486
+ if ( isMethodCall ) {
487
+ this.each(function() {
488
+ var methodValue,
489
+ instance = $.data( this, fullName );
490
+ if ( !instance ) {
491
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
492
+ "attempted to call method '" + options + "'" );
493
+ }
494
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
495
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
496
+ }
497
+ methodValue = instance[ options ].apply( instance, args );
498
+ if ( methodValue !== instance && methodValue !== undefined ) {
499
+ returnValue = methodValue && methodValue.jquery ?
500
+ returnValue.pushStack( methodValue.get() ) :
501
+ methodValue;
502
+ return false;
503
+ }
504
+ });
505
+ } else {
506
+ this.each(function() {
507
+ var instance = $.data( this, fullName );
508
+ if ( instance ) {
509
+ instance.option( options || {} )._init();
510
+ } else {
511
+ $.data( this, fullName, new object( options, this ) );
512
+ }
513
+ });
514
+ }
515
+
516
+ return returnValue;
517
+ };
518
+ };
519
+
520
+ $.Widget = function( /* options, element */ ) {};
521
+ $.Widget._childConstructors = [];
522
+
523
+ $.Widget.prototype = {
524
+ widgetName: "widget",
525
+ widgetEventPrefix: "",
526
+ defaultElement: "<div>",
527
+ options: {
528
+ disabled: false,
529
+
530
+ // callbacks
531
+ create: null
532
+ },
533
+ _createWidget: function( options, element ) {
534
+ element = $( element || this.defaultElement || this )[ 0 ];
535
+ this.element = $( element );
536
+ this.uuid = uuid++;
537
+ this.eventNamespace = "." + this.widgetName + this.uuid;
538
+ this.options = $.widget.extend( {},
539
+ this.options,
540
+ this._getCreateOptions(),
541
+ options );
542
+
543
+ this.bindings = $();
544
+ this.hoverable = $();
545
+ this.focusable = $();
546
+
547
+ if ( element !== this ) {
548
+ $.data( element, this.widgetFullName, this );
549
+ this._on( true, this.element, {
550
+ remove: function( event ) {
551
+ if ( event.target === element ) {
552
+ this.destroy();
553
+ }
554
+ }
555
+ });
556
+ this.document = $( element.style ?
557
+ // element within the document
558
+ element.ownerDocument :
559
+ // element is window or document
560
+ element.document || element );
561
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
562
+ }
563
+
564
+ this._create();
565
+ this._trigger( "create", null, this._getCreateEventData() );
566
+ this._init();
567
+ },
568
+ _getCreateOptions: $.noop,
569
+ _getCreateEventData: $.noop,
570
+ _create: $.noop,
571
+ _init: $.noop,
572
+
573
+ destroy: function() {
574
+ this._destroy();
575
+ // we can probably remove the unbind calls in 2.0
576
+ // all event bindings should go through this._on()
577
+ this.element
578
+ .unbind( this.eventNamespace )
579
+ // 1.9 BC for #7810
580
+ // TODO remove dual storage
581
+ .removeData( this.widgetName )
582
+ .removeData( this.widgetFullName )
583
+ // support: jquery <1.6.3
584
+ // http://bugs.jquery.com/ticket/9413
585
+ .removeData( $.camelCase( this.widgetFullName ) );
586
+ this.widget()
587
+ .unbind( this.eventNamespace )
588
+ .removeAttr( "aria-disabled" )
589
+ .removeClass(
590
+ this.widgetFullName + "-disabled " +
591
+ "ui-state-disabled" );
592
+
593
+ // clean up events and states
594
+ this.bindings.unbind( this.eventNamespace );
595
+ this.hoverable.removeClass( "ui-state-hover" );
596
+ this.focusable.removeClass( "ui-state-focus" );
597
+ },
598
+ _destroy: $.noop,
599
+
600
+ widget: function() {
601
+ return this.element;
602
+ },
603
+
604
+ option: function( key, value ) {
605
+ var options = key,
606
+ parts,
607
+ curOption,
608
+ i;
609
+
610
+ if ( arguments.length === 0 ) {
611
+ // don't return a reference to the internal hash
612
+ return $.widget.extend( {}, this.options );
613
+ }
614
+
615
+ if ( typeof key === "string" ) {
616
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
617
+ options = {};
618
+ parts = key.split( "." );
619
+ key = parts.shift();
620
+ if ( parts.length ) {
621
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
622
+ for ( i = 0; i < parts.length - 1; i++ ) {
623
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
624
+ curOption = curOption[ parts[ i ] ];
625
+ }
626
+ key = parts.pop();
627
+ if ( value === undefined ) {
628
+ return curOption[ key ] === undefined ? null : curOption[ key ];
629
+ }
630
+ curOption[ key ] = value;
631
+ } else {
632
+ if ( value === undefined ) {
633
+ return this.options[ key ] === undefined ? null : this.options[ key ];
634
+ }
635
+ options[ key ] = value;
636
+ }
637
+ }
638
+
639
+ this._setOptions( options );
640
+
641
+ return this;
642
+ },
643
+ _setOptions: function( options ) {
644
+ var key;
645
+
646
+ for ( key in options ) {
647
+ this._setOption( key, options[ key ] );
648
+ }
649
+
650
+ return this;
651
+ },
652
+ _setOption: function( key, value ) {
653
+ this.options[ key ] = value;
654
+
655
+ if ( key === "disabled" ) {
656
+ this.widget()
657
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
658
+ .attr( "aria-disabled", value );
659
+ this.hoverable.removeClass( "ui-state-hover" );
660
+ this.focusable.removeClass( "ui-state-focus" );
661
+ }
662
+
663
+ return this;
664
+ },
665
+
666
+ enable: function() {
667
+ return this._setOption( "disabled", false );
668
+ },
669
+ disable: function() {
670
+ return this._setOption( "disabled", true );
671
+ },
672
+
673
+ _on: function( suppressDisabledCheck, element, handlers ) {
674
+ var delegateElement,
675
+ instance = this;
676
+
677
+ // no suppressDisabledCheck flag, shuffle arguments
678
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
679
+ handlers = element;
680
+ element = suppressDisabledCheck;
681
+ suppressDisabledCheck = false;
682
+ }
683
+
684
+ // no element argument, shuffle and use this.element
685
+ if ( !handlers ) {
686
+ handlers = element;
687
+ element = this.element;
688
+ delegateElement = this.widget();
689
+ } else {
690
+ // accept selectors, DOM elements
691
+ element = delegateElement = $( element );
692
+ this.bindings = this.bindings.add( element );
693
+ }
694
+
695
+ $.each( handlers, function( event, handler ) {
696
+ function handlerProxy() {
697
+ // allow widgets to customize the disabled handling
698
+ // - disabled as an array instead of boolean
699
+ // - disabled class as method for disabling individual parts
700
+ if ( !suppressDisabledCheck &&
701
+ ( instance.options.disabled === true ||
702
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
703
+ return;
704
+ }
705
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
706
+ .apply( instance, arguments );
707
+ }
708
+
709
+ // copy the guid so direct unbinding works
710
+ if ( typeof handler !== "string" ) {
711
+ handlerProxy.guid = handler.guid =
712
+ handler.guid || handlerProxy.guid || $.guid++;
713
+ }
714
+
715
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
716
+ eventName = match[1] + instance.eventNamespace,
717
+ selector = match[2];
718
+ if ( selector ) {
719
+ delegateElement.delegate( selector, eventName, handlerProxy );
720
+ } else {
721
+ element.bind( eventName, handlerProxy );
722
+ }
723
+ });
724
+ },
725
+
726
+ _off: function( element, eventName ) {
727
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
728
+ element.unbind( eventName ).undelegate( eventName );
729
+ },
730
+
731
+ _delay: function( handler, delay ) {
732
+ function handlerProxy() {
733
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
734
+ .apply( instance, arguments );
735
+ }
736
+ var instance = this;
737
+ return setTimeout( handlerProxy, delay || 0 );
738
+ },
739
+
740
+ _hoverable: function( element ) {
741
+ this.hoverable = this.hoverable.add( element );
742
+ this._on( element, {
743
+ mouseenter: function( event ) {
744
+ $( event.currentTarget ).addClass( "ui-state-hover" );
745
+ },
746
+ mouseleave: function( event ) {
747
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
748
+ }
749
+ });
750
+ },
751
+
752
+ _focusable: function( element ) {
753
+ this.focusable = this.focusable.add( element );
754
+ this._on( element, {
755
+ focusin: function( event ) {
756
+ $( event.currentTarget ).addClass( "ui-state-focus" );
757
+ },
758
+ focusout: function( event ) {
759
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
760
+ }
761
+ });
762
+ },
763
+
764
+ _trigger: function( type, event, data ) {
765
+ var prop, orig,
766
+ callback = this.options[ type ];
767
+
768
+ data = data || {};
769
+ event = $.Event( event );
770
+ event.type = ( type === this.widgetEventPrefix ?
771
+ type :
772
+ this.widgetEventPrefix + type ).toLowerCase();
773
+ // the original event may come from any element
774
+ // so we need to reset the target on the new event
775
+ event.target = this.element[ 0 ];
776
+
777
+ // copy original event properties over to the new event
778
+ orig = event.originalEvent;
779
+ if ( orig ) {
780
+ for ( prop in orig ) {
781
+ if ( !( prop in event ) ) {
782
+ event[ prop ] = orig[ prop ];
783
+ }
784
+ }
785
+ }
786
+
787
+ this.element.trigger( event, data );
788
+ return !( $.isFunction( callback ) &&
789
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
790
+ event.isDefaultPrevented() );
791
+ }
792
+ };
793
+
794
+ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
795
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
796
+ if ( typeof options === "string" ) {
797
+ options = { effect: options };
798
+ }
799
+ var hasOptions,
800
+ effectName = !options ?
801
+ method :
802
+ options === true || typeof options === "number" ?
803
+ defaultEffect :
804
+ options.effect || defaultEffect;
805
+ options = options || {};
806
+ if ( typeof options === "number" ) {
807
+ options = { duration: options };
808
+ }
809
+ hasOptions = !$.isEmptyObject( options );
810
+ options.complete = callback;
811
+ if ( options.delay ) {
812
+ element.delay( options.delay );
813
+ }
814
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
815
+ element[ method ]( options );
816
+ } else if ( effectName !== method && element[ effectName ] ) {
817
+ element[ effectName ]( options.duration, options.easing, callback );
818
+ } else {
819
+ element.queue(function( next ) {
820
+ $( this )[ method ]();
821
+ if ( callback ) {
822
+ callback.call( element[ 0 ] );
823
+ }
824
+ next();
825
+ });
826
+ }
827
+ };
828
+ });
829
+
830
+ })( jQuery );
831
+ (function( $, undefined ) {
832
+
833
+ var mouseHandled = false;
834
+ $( document ).mouseup( function() {
835
+ mouseHandled = false;
836
+ });
837
+
838
+ $.widget("ui.mouse", {
839
+ version: "1.10.1",
840
+ options: {
841
+ cancel: "input,textarea,button,select,option",
842
+ distance: 1,
843
+ delay: 0
844
+ },
845
+ _mouseInit: function() {
846
+ var that = this;
847
+
848
+ this.element
849
+ .bind("mousedown."+this.widgetName, function(event) {
850
+ return that._mouseDown(event);
851
+ })
852
+ .bind("click."+this.widgetName, function(event) {
853
+ if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
854
+ $.removeData(event.target, that.widgetName + ".preventClickEvent");
855
+ event.stopImmediatePropagation();
856
+ return false;
857
+ }
858
+ });
859
+
860
+ this.started = false;
861
+ },
862
+
863
+ // TODO: make sure destroying one instance of mouse doesn't mess with
864
+ // other instances of mouse
865
+ _mouseDestroy: function() {
866
+ this.element.unbind("."+this.widgetName);
867
+ if ( this._mouseMoveDelegate ) {
868
+ $(document)
869
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
870
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
871
+ }
872
+ },
873
+
874
+ _mouseDown: function(event) {
875
+ // don't let more than one widget handle mouseStart
876
+ if( mouseHandled ) { return; }
877
+
878
+ // we may have missed mouseup (out of window)
879
+ (this._mouseStarted && this._mouseUp(event));
880
+
881
+ this._mouseDownEvent = event;
882
+
883
+ var that = this,
884
+ btnIsLeft = (event.which === 1),
885
+ // event.target.nodeName works around a bug in IE 8 with
886
+ // disabled inputs (#7620)
887
+ elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
888
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
889
+ return true;
890
+ }
891
+
892
+ this.mouseDelayMet = !this.options.delay;
893
+ if (!this.mouseDelayMet) {
894
+ this._mouseDelayTimer = setTimeout(function() {
895
+ that.mouseDelayMet = true;
896
+ }, this.options.delay);
897
+ }
898
+
899
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
900
+ this._mouseStarted = (this._mouseStart(event) !== false);
901
+ if (!this._mouseStarted) {
902
+ event.preventDefault();
903
+ return true;
904
+ }
905
+ }
906
+
907
+ // Click event may never have fired (Gecko & Opera)
908
+ if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
909
+ $.removeData(event.target, this.widgetName + ".preventClickEvent");
910
+ }
911
+
912
+ // these delegates are required to keep context
913
+ this._mouseMoveDelegate = function(event) {
914
+ return that._mouseMove(event);
915
+ };
916
+ this._mouseUpDelegate = function(event) {
917
+ return that._mouseUp(event);
918
+ };
919
+ $(document)
920
+ .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
921
+ .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
922
+
923
+ event.preventDefault();
924
+
925
+ mouseHandled = true;
926
+ return true;
927
+ },
928
+
929
+ _mouseMove: function(event) {
930
+ // IE mouseup check - mouseup happened when mouse was out of window
931
+ if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
932
+ return this._mouseUp(event);
933
+ }
934
+
935
+ if (this._mouseStarted) {
936
+ this._mouseDrag(event);
937
+ return event.preventDefault();
938
+ }
939
+
940
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941
+ this._mouseStarted =
942
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
943
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
944
+ }
945
+
946
+ return !this._mouseStarted;
947
+ },
948
+
949
+ _mouseUp: function(event) {
950
+ $(document)
951
+ .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
952
+ .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
953
+
954
+ if (this._mouseStarted) {
955
+ this._mouseStarted = false;
956
+
957
+ if (event.target === this._mouseDownEvent.target) {
958
+ $.data(event.target, this.widgetName + ".preventClickEvent", true);
959
+ }
960
+
961
+ this._mouseStop(event);
962
+ }
963
+
964
+ return false;
965
+ },
966
+
967
+ _mouseDistanceMet: function(event) {
968
+ return (Math.max(
969
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
970
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
971
+ ) >= this.options.distance
972
+ );
973
+ },
974
+
975
+ _mouseDelayMet: function(/* event */) {
976
+ return this.mouseDelayMet;
977
+ },
978
+
979
+ // These are placeholder methods, to be overriden by extending plugin
980
+ _mouseStart: function(/* event */) {},
981
+ _mouseDrag: function(/* event */) {},
982
+ _mouseStop: function(/* event */) {},
983
+ _mouseCapture: function(/* event */) { return true; }
984
+ });
985
+
986
+ })(jQuery);
987
+ (function( $, undefined ) {
988
+
989
+ /*jshint loopfunc: true */
990
+
991
+ function isOverAxis( x, reference, size ) {
992
+ return ( x > reference ) && ( x < ( reference + size ) );
993
+ }
994
+
995
+ $.widget("ui.sortable", $.ui.mouse, {
996
+ version: "1.10.1",
997
+ widgetEventPrefix: "sort",
998
+ ready: false,
999
+ options: {
1000
+ appendTo: "parent",
1001
+ axis: false,
1002
+ connectWith: false,
1003
+ containment: false,
1004
+ cursor: "auto",
1005
+ cursorAt: false,
1006
+ dropOnEmpty: true,
1007
+ forcePlaceholderSize: false,
1008
+ forceHelperSize: false,
1009
+ grid: false,
1010
+ handle: false,
1011
+ helper: "original",
1012
+ items: "> *",
1013
+ opacity: false,
1014
+ placeholder: false,
1015
+ revert: false,
1016
+ scroll: true,
1017
+ scrollSensitivity: 20,
1018
+ scrollSpeed: 20,
1019
+ scope: "default",
1020
+ tolerance: "intersect",
1021
+ zIndex: 1000,
1022
+
1023
+ // callbacks
1024
+ activate: null,
1025
+ beforeStop: null,
1026
+ change: null,
1027
+ deactivate: null,
1028
+ out: null,
1029
+ over: null,
1030
+ receive: null,
1031
+ remove: null,
1032
+ sort: null,
1033
+ start: null,
1034
+ stop: null,
1035
+ update: null
1036
+ },
1037
+ _create: function() {
1038
+
1039
+ var o = this.options;
1040
+ this.containerCache = {};
1041
+ this.element.addClass("ui-sortable");
1042
+
1043
+ //Get the items
1044
+ this.refresh();
1045
+
1046
+ //Let's determine if the items are being displayed horizontally
1047
+ 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;
1048
+
1049
+ //Let's determine the parent's offset
1050
+ this.offset = this.element.offset();
1051
+
1052
+ //Initialize mouse events for interaction
1053
+ this._mouseInit();
1054
+
1055
+ //We're ready to go
1056
+ this.ready = true;
1057
+
1058
+ },
1059
+
1060
+ _destroy: function() {
1061
+ this.element
1062
+ .removeClass("ui-sortable ui-sortable-disabled");
1063
+ this._mouseDestroy();
1064
+
1065
+ for ( var i = this.items.length - 1; i >= 0; i-- ) {
1066
+ this.items[i].item.removeData(this.widgetName + "-item");
1067
+ }
1068
+
1069
+ return this;
1070
+ },
1071
+
1072
+ _setOption: function(key, value){
1073
+ if ( key === "disabled" ) {
1074
+ this.options[ key ] = value;
1075
+
1076
+ this.widget().toggleClass( "ui-sortable-disabled", !!value );
1077
+ } else {
1078
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
1079
+ $.Widget.prototype._setOption.apply(this, arguments);
1080
+ }
1081
+ },
1082
+
1083
+ _mouseCapture: function(event, overrideHandle) {
1084
+ var currentItem = null,
1085
+ validHandle = false,
1086
+ that = this;
1087
+
1088
+ if (this.reverting) {
1089
+ return false;
1090
+ }
1091
+
1092
+ if(this.options.disabled || this.options.type === "static") {
1093
+ return false;
1094
+ }
1095
+
1096
+ //We have to refresh the items data once first
1097
+ this._refreshItems(event);
1098
+
1099
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
1100
+ $(event.target).parents().each(function() {
1101
+ if($.data(this, that.widgetName + "-item") === that) {
1102
+ currentItem = $(this);
1103
+ return false;
1104
+ }
1105
+ });
1106
+ if($.data(event.target, that.widgetName + "-item") === that) {
1107
+ currentItem = $(event.target);
1108
+ }
1109
+
1110
+ if(!currentItem) {
1111
+ return false;
1112
+ }
1113
+ if(this.options.handle && !overrideHandle) {
1114
+ $(this.options.handle, currentItem).find("*").addBack().each(function() {
1115
+ if(this === event.target) {
1116
+ validHandle = true;
1117
+ }
1118
+ });
1119
+ if(!validHandle) {
1120
+ return false;
1121
+ }
1122
+ }
1123
+
1124
+ this.currentItem = currentItem;
1125
+ this._removeCurrentsFromItems();
1126
+ return true;
1127
+
1128
+ },
1129
+
1130
+ _mouseStart: function(event, overrideHandle, noActivation) {
1131
+
1132
+ var i,
1133
+ o = this.options;
1134
+
1135
+ this.currentContainer = this;
1136
+
1137
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
1138
+ this.refreshPositions();
1139
+
1140
+ //Create and append the visible helper
1141
+ this.helper = this._createHelper(event);
1142
+
1143
+ //Cache the helper size
1144
+ this._cacheHelperProportions();
1145
+
1146
+ /*
1147
+ * - Position generation -
1148
+ * This block generates everything position related - it's the core of draggables.
1149
+ */
1150
+
1151
+ //Cache the margins of the original element
1152
+ this._cacheMargins();
1153
+
1154
+ //Get the next scrolling parent
1155
+ this.scrollParent = this.helper.scrollParent();
1156
+
1157
+ //The element's absolute position on the page minus margins
1158
+ this.offset = this.currentItem.offset();
1159
+ this.offset = {
1160
+ top: this.offset.top - this.margins.top,
1161
+ left: this.offset.left - this.margins.left
1162
+ };
1163
+
1164
+ $.extend(this.offset, {
1165
+ click: { //Where the click happened, relative to the element
1166
+ left: event.pageX - this.offset.left,
1167
+ top: event.pageY - this.offset.top
1168
+ },
1169
+ parent: this._getParentOffset(),
1170
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1171
+ });
1172
+
1173
+ // Only after we got the offset, we can change the helper's position to absolute
1174
+ // TODO: Still need to figure out a way to make relative sorting possible
1175
+ this.helper.css("position", "absolute");
1176
+ this.cssPosition = this.helper.css("position");
1177
+
1178
+ //Generate the original position
1179
+ this.originalPosition = this._generatePosition(event);
1180
+ this.originalPageX = event.pageX;
1181
+ this.originalPageY = event.pageY;
1182
+
1183
+ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1184
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1185
+
1186
+ //Cache the former DOM position
1187
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
1188
+
1189
+ //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
1190
+ if(this.helper[0] !== this.currentItem[0]) {
1191
+ this.currentItem.hide();
1192
+ }
1193
+
1194
+ //Create the placeholder
1195
+ this._createPlaceholder();
1196
+
1197
+ //Set a containment if given in the options
1198
+ if(o.containment) {
1199
+ this._setContainment();
1200
+ }
1201
+
1202
+ if(o.cursor) { // cursor option
1203
+ if ($("body").css("cursor")) {
1204
+ this._storedCursor = $("body").css("cursor");
1205
+ }
1206
+ $("body").css("cursor", o.cursor);
1207
+ }
1208
+
1209
+ if(o.opacity) { // opacity option
1210
+ if (this.helper.css("opacity")) {
1211
+ this._storedOpacity = this.helper.css("opacity");
1212
+ }
1213
+ this.helper.css("opacity", o.opacity);
1214
+ }
1215
+
1216
+ if(o.zIndex) { // zIndex option
1217
+ if (this.helper.css("zIndex")) {
1218
+ this._storedZIndex = this.helper.css("zIndex");
1219
+ }
1220
+ this.helper.css("zIndex", o.zIndex);
1221
+ }
1222
+
1223
+ //Prepare scrolling
1224
+ if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1225
+ this.overflowOffset = this.scrollParent.offset();
1226
+ }
1227
+
1228
+ //Call callbacks
1229
+ this._trigger("start", event, this._uiHash());
1230
+
1231
+ //Recache the helper size
1232
+ if(!this._preserveHelperProportions) {
1233
+ this._cacheHelperProportions();
1234
+ }
1235
+
1236
+
1237
+ //Post "activate" events to possible containers
1238
+ if( !noActivation ) {
1239
+ for ( i = this.containers.length - 1; i >= 0; i-- ) {
1240
+ this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
1241
+ }
1242
+ }
1243
+
1244
+ //Prepare possible droppables
1245
+ if($.ui.ddmanager) {
1246
+ $.ui.ddmanager.current = this;
1247
+ }
1248
+
1249
+ if ($.ui.ddmanager && !o.dropBehaviour) {
1250
+ $.ui.ddmanager.prepareOffsets(this, event);
1251
+ }
1252
+
1253
+ this.dragging = true;
1254
+
1255
+ this.helper.addClass("ui-sortable-helper");
1256
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1257
+ return true;
1258
+
1259
+ },
1260
+
1261
+ _mouseDrag: function(event) {
1262
+ var i, item, itemElement, intersection,
1263
+ o = this.options,
1264
+ scrolled = false;
1265
+
1266
+ //Compute the helpers position
1267
+ this.position = this._generatePosition(event);
1268
+ this.positionAbs = this._convertPositionTo("absolute");
1269
+
1270
+ if (!this.lastPositionAbs) {
1271
+ this.lastPositionAbs = this.positionAbs;
1272
+ }
1273
+
1274
+ //Do scrolling
1275
+ if(this.options.scroll) {
1276
+ if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
1277
+
1278
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1279
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
1280
+ } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
1281
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
1282
+ }
1283
+
1284
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1285
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
1286
+ } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
1287
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
1288
+ }
1289
+
1290
+ } else {
1291
+
1292
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1293
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1294
+ } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1295
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1296
+ }
1297
+
1298
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1299
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1300
+ } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1301
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1302
+ }
1303
+
1304
+ }
1305
+
1306
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1307
+ $.ui.ddmanager.prepareOffsets(this, event);
1308
+ }
1309
+ }
1310
+
1311
+ //Regenerate the absolute position used for position checks
1312
+ this.positionAbs = this._convertPositionTo("absolute");
1313
+
1314
+ //Set the helper position
1315
+ if(!this.options.axis || this.options.axis !== "y") {
1316
+ this.helper[0].style.left = this.position.left+"px";
1317
+ }
1318
+ if(!this.options.axis || this.options.axis !== "x") {
1319
+ this.helper[0].style.top = this.position.top+"px";
1320
+ }
1321
+
1322
+ //Rearrange
1323
+ for (i = this.items.length - 1; i >= 0; i--) {
1324
+
1325
+ //Cache variables and intersection, continue if no intersection
1326
+ item = this.items[i];
1327
+ itemElement = item.item[0];
1328
+ intersection = this._intersectsWithPointer(item);
1329
+ if (!intersection) {
1330
+ continue;
1331
+ }
1332
+
1333
+ // Only put the placeholder inside the current Container, skip all
1334
+ // items form other containers. This works because when moving
1335
+ // an item from one container to another the
1336
+ // currentContainer is switched before the placeholder is moved.
1337
+ //
1338
+ // Without this moving items in "sub-sortables" can cause the placeholder to jitter
1339
+ // beetween the outer and inner container.
1340
+ if (item.instance !== this.currentContainer) {
1341
+ continue;
1342
+ }
1343
+
1344
+ // cannot intersect with itself
1345
+ // no useless actions that have been done before
1346
+ // no action if the item moved is the parent of the item checked
1347
+ if (itemElement !== this.currentItem[0] &&
1348
+ this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
1349
+ !$.contains(this.placeholder[0], itemElement) &&
1350
+ (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
1351
+ ) {
1352
+
1353
+ this.direction = intersection === 1 ? "down" : "up";
1354
+
1355
+ if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
1356
+ this._rearrange(event, item);
1357
+ } else {
1358
+ break;
1359
+ }
1360
+
1361
+ this._trigger("change", event, this._uiHash());
1362
+ break;
1363
+ }
1364
+ }
1365
+
1366
+ //Post events to containers
1367
+ this._contactContainers(event);
1368
+
1369
+ //Interconnect with droppables
1370
+ if($.ui.ddmanager) {
1371
+ $.ui.ddmanager.drag(this, event);
1372
+ }
1373
+
1374
+ //Call callbacks
1375
+ this._trigger("sort", event, this._uiHash());
1376
+
1377
+ this.lastPositionAbs = this.positionAbs;
1378
+ return false;
1379
+
1380
+ },
1381
+
1382
+ _mouseStop: function(event, noPropagation) {
1383
+
1384
+ if(!event) {
1385
+ return;
1386
+ }
1387
+
1388
+ //If we are using droppables, inform the manager about the drop
1389
+ if ($.ui.ddmanager && !this.options.dropBehaviour) {
1390
+ $.ui.ddmanager.drop(this, event);
1391
+ }
1392
+
1393
+ if(this.options.revert) {
1394
+ var that = this,
1395
+ cur = this.placeholder.offset();
1396
+
1397
+ this.reverting = true;
1398
+
1399
+ $(this.helper).animate({
1400
+ left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft),
1401
+ top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop)
1402
+ }, parseInt(this.options.revert, 10) || 500, function() {
1403
+ that._clear(event);
1404
+ });
1405
+ } else {
1406
+ this._clear(event, noPropagation);
1407
+ }
1408
+
1409
+ return false;
1410
+
1411
+ },
1412
+
1413
+ cancel: function() {
1414
+
1415
+ if(this.dragging) {
1416
+
1417
+ this._mouseUp({ target: null });
1418
+
1419
+ if(this.options.helper === "original") {
1420
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1421
+ } else {
1422
+ this.currentItem.show();
1423
+ }
1424
+
1425
+ //Post deactivating events to containers
1426
+ for (var i = this.containers.length - 1; i >= 0; i--){
1427
+ this.containers[i]._trigger("deactivate", null, this._uiHash(this));
1428
+ if(this.containers[i].containerCache.over) {
1429
+ this.containers[i]._trigger("out", null, this._uiHash(this));
1430
+ this.containers[i].containerCache.over = 0;
1431
+ }
1432
+ }
1433
+
1434
+ }
1435
+
1436
+ if (this.placeholder) {
1437
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1438
+ if(this.placeholder[0].parentNode) {
1439
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1440
+ }
1441
+ if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
1442
+ this.helper.remove();
1443
+ }
1444
+
1445
+ $.extend(this, {
1446
+ helper: null,
1447
+ dragging: false,
1448
+ reverting: false,
1449
+ _noFinalSort: null
1450
+ });
1451
+
1452
+ if(this.domPosition.prev) {
1453
+ $(this.domPosition.prev).after(this.currentItem);
1454
+ } else {
1455
+ $(this.domPosition.parent).prepend(this.currentItem);
1456
+ }
1457
+ }
1458
+
1459
+ return this;
1460
+
1461
+ },
1462
+
1463
+ serialize: function(o) {
1464
+
1465
+ var items = this._getItemsAsjQuery(o && o.connected),
1466
+ str = [];
1467
+ o = o || {};
1468
+
1469
+ $(items).each(function() {
1470
+ var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
1471
+ if (res) {
1472
+ str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
1473
+ }
1474
+ });
1475
+
1476
+ if(!str.length && o.key) {
1477
+ str.push(o.key + "=");
1478
+ }
1479
+
1480
+ return str.join("&");
1481
+
1482
+ },
1483
+
1484
+ toArray: function(o) {
1485
+
1486
+ var items = this._getItemsAsjQuery(o && o.connected),
1487
+ ret = [];
1488
+
1489
+ o = o || {};
1490
+
1491
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
1492
+ return ret;
1493
+
1494
+ },
1495
+
1496
+ /* Be careful with the following core functions */
1497
+ _intersectsWith: function(item) {
1498
+
1499
+ var x1 = this.positionAbs.left,
1500
+ x2 = x1 + this.helperProportions.width,
1501
+ y1 = this.positionAbs.top,
1502
+ y2 = y1 + this.helperProportions.height,
1503
+ l = item.left,
1504
+ r = l + item.width,
1505
+ t = item.top,
1506
+ b = t + item.height,
1507
+ dyClick = this.offset.click.top,
1508
+ dxClick = this.offset.click.left,
1509
+ isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
1510
+
1511
+ if ( this.options.tolerance === "pointer" ||
1512
+ this.options.forcePointerForContainers ||
1513
+ (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
1514
+ ) {
1515
+ return isOverElement;
1516
+ } else {
1517
+
1518
+ return (l < x1 + (this.helperProportions.width / 2) && // Right Half
1519
+ x2 - (this.helperProportions.width / 2) < r && // Left Half
1520
+ t < y1 + (this.helperProportions.height / 2) && // Bottom Half
1521
+ y2 - (this.helperProportions.height / 2) < b ); // Top Half
1522
+
1523
+ }
1524
+ },
1525
+
1526
+ _intersectsWithPointer: function(item) {
1527
+
1528
+ var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
1529
+ isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
1530
+ isOverElement = isOverElementHeight && isOverElementWidth,
1531
+ verticalDirection = this._getDragVerticalDirection(),
1532
+ horizontalDirection = this._getDragHorizontalDirection();
1533
+
1534
+ if (!isOverElement) {
1535
+ return false;
1536
+ }
1537
+
1538
+ return this.floating ?
1539
+ ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
1540
+ : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
1541
+
1542
+ },
1543
+
1544
+ _intersectsWithSides: function(item) {
1545
+
1546
+ var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
1547
+ isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
1548
+ verticalDirection = this._getDragVerticalDirection(),
1549
+ horizontalDirection = this._getDragHorizontalDirection();
1550
+
1551
+ if (this.floating && horizontalDirection) {
1552
+ return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
1553
+ } else {
1554
+ return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
1555
+ }
1556
+
1557
+ },
1558
+
1559
+ _getDragVerticalDirection: function() {
1560
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
1561
+ return delta !== 0 && (delta > 0 ? "down" : "up");
1562
+ },
1563
+
1564
+ _getDragHorizontalDirection: function() {
1565
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
1566
+ return delta !== 0 && (delta > 0 ? "right" : "left");
1567
+ },
1568
+
1569
+ refresh: function(event) {
1570
+ this._refreshItems(event);
1571
+ this.refreshPositions();
1572
+ return this;
1573
+ },
1574
+
1575
+ _connectWith: function() {
1576
+ var options = this.options;
1577
+ return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
1578
+ },
1579
+
1580
+ _getItemsAsjQuery: function(connected) {
1581
+
1582
+ var i, j, cur, inst,
1583
+ items = [],
1584
+ queries = [],
1585
+ connectWith = this._connectWith();
1586
+
1587
+ if(connectWith && connected) {
1588
+ for (i = connectWith.length - 1; i >= 0; i--){
1589
+ cur = $(connectWith[i]);
1590
+ for ( j = cur.length - 1; j >= 0; j--){
1591
+ inst = $.data(cur[j], this.widgetFullName);
1592
+ if(inst && inst !== this && !inst.options.disabled) {
1593
+ 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]);
1594
+ }
1595
+ }
1596
+ }
1597
+ }
1598
+
1599
+ 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]);
1600
+
1601
+ for (i = queries.length - 1; i >= 0; i--){
1602
+ queries[i][0].each(function() {
1603
+ items.push(this);
1604
+ });
1605
+ }
1606
+
1607
+ return $(items);
1608
+
1609
+ },
1610
+
1611
+ _removeCurrentsFromItems: function() {
1612
+
1613
+ var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
1614
+
1615
+ this.items = $.grep(this.items, function (item) {
1616
+ for (var j=0; j < list.length; j++) {
1617
+ if(list[j] === item.item[0]) {
1618
+ return false;
1619
+ }
1620
+ }
1621
+ return true;
1622
+ });
1623
+
1624
+ },
1625
+
1626
+ _refreshItems: function(event) {
1627
+
1628
+ this.items = [];
1629
+ this.containers = [this];
1630
+
1631
+ var i, j, cur, inst, targetData, _queries, item, queriesLength,
1632
+ items = this.items,
1633
+ queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
1634
+ connectWith = this._connectWith();
1635
+
1636
+ if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
1637
+ for (i = connectWith.length - 1; i >= 0; i--){
1638
+ cur = $(connectWith[i]);
1639
+ for (j = cur.length - 1; j >= 0; j--){
1640
+ inst = $.data(cur[j], this.widgetFullName);
1641
+ if(inst && inst !== this && !inst.options.disabled) {
1642
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
1643
+ this.containers.push(inst);
1644
+ }
1645
+ }
1646
+ }
1647
+ }
1648
+
1649
+ for (i = queries.length - 1; i >= 0; i--) {
1650
+ targetData = queries[i][1];
1651
+ _queries = queries[i][0];
1652
+
1653
+ for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
1654
+ item = $(_queries[j]);
1655
+
1656
+ item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
1657
+
1658
+ items.push({
1659
+ item: item,
1660
+ instance: targetData,
1661
+ width: 0, height: 0,
1662
+ left: 0, top: 0
1663
+ });
1664
+ }
1665
+ }
1666
+
1667
+ },
1668
+
1669
+ refreshPositions: function(fast) {
1670
+
1671
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
1672
+ if(this.offsetParent && this.helper) {
1673
+ this.offset.parent = this._getParentOffset();
1674
+ }
1675
+
1676
+ var i, item, t, p;
1677
+
1678
+ for (i = this.items.length - 1; i >= 0; i--){
1679
+ item = this.items[i];
1680
+
1681
+ //We ignore calculating positions of all connected containers when we're not over them
1682
+ if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
1683
+ continue;
1684
+ }
1685
+
1686
+ t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
1687
+
1688
+ if (!fast) {
1689
+ item.width = t.outerWidth();
1690
+ item.height = t.outerHeight();
1691
+ }
1692
+
1693
+ p = t.offset();
1694
+ item.left = p.left;
1695
+ item.top = p.top;
1696
+ }
1697
+
1698
+ if(this.options.custom && this.options.custom.refreshContainers) {
1699
+ this.options.custom.refreshContainers.call(this);
1700
+ } else {
1701
+ for (i = this.containers.length - 1; i >= 0; i--){
1702
+ p = this.containers[i].element.offset();
1703
+ this.containers[i].containerCache.left = p.left;
1704
+ this.containers[i].containerCache.top = p.top;
1705
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
1706
+ this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
1707
+ }
1708
+ }
1709
+
1710
+ return this;
1711
+ },
1712
+
1713
+ _createPlaceholder: function(that) {
1714
+ that = that || this;
1715
+ var className,
1716
+ o = that.options;
1717
+
1718
+ if(!o.placeholder || o.placeholder.constructor === String) {
1719
+ className = o.placeholder;
1720
+ o.placeholder = {
1721
+ element: function() {
1722
+
1723
+ var el = $(document.createElement(that.currentItem[0].nodeName))
1724
+ .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
1725
+ .removeClass("ui-sortable-helper")[0];
1726
+
1727
+ if(!className) {
1728
+ el.style.visibility = "hidden";
1729
+ }
1730
+
1731
+ return el;
1732
+ },
1733
+ update: function(container, p) {
1734
+
1735
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
1736
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
1737
+ if(className && !o.forcePlaceholderSize) {
1738
+ return;
1739
+ }
1740
+
1741
+ //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
1742
+ if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
1743
+ if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
1744
+ }
1745
+ };
1746
+ }
1747
+
1748
+ //Create the placeholder
1749
+ that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
1750
+
1751
+ //Append it after the actual current item
1752
+ that.currentItem.after(that.placeholder);
1753
+
1754
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
1755
+ o.placeholder.update(that, that.placeholder);
1756
+
1757
+ },
1758
+
1759
+ _contactContainers: function(event) {
1760
+ var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
1761
+ innermostContainer = null,
1762
+ innermostIndex = null;
1763
+
1764
+ // get innermost container that intersects with item
1765
+ for (i = this.containers.length - 1; i >= 0; i--) {
1766
+
1767
+ // never consider a container that's located within the item itself
1768
+ if($.contains(this.currentItem[0], this.containers[i].element[0])) {
1769
+ continue;
1770
+ }
1771
+
1772
+ if(this._intersectsWith(this.containers[i].containerCache)) {
1773
+
1774
+ // if we've already found a container and it's more "inner" than this, then continue
1775
+ if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
1776
+ continue;
1777
+ }
1778
+
1779
+ innermostContainer = this.containers[i];
1780
+ innermostIndex = i;
1781
+
1782
+ } else {
1783
+ // container doesn't intersect. trigger "out" event if necessary
1784
+ if(this.containers[i].containerCache.over) {
1785
+ this.containers[i]._trigger("out", event, this._uiHash(this));
1786
+ this.containers[i].containerCache.over = 0;
1787
+ }
1788
+ }
1789
+
1790
+ }
1791
+
1792
+ // if no intersecting containers found, return
1793
+ if(!innermostContainer) {
1794
+ return;
1795
+ }
1796
+
1797
+ // move the item into the container if it's not there already
1798
+ if(this.containers.length === 1) {
1799
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1800
+ this.containers[innermostIndex].containerCache.over = 1;
1801
+ } else {
1802
+
1803
+ //When entering a new container, we will find the item with the least distance and append our item near it
1804
+ dist = 10000;
1805
+ itemWithLeastDistance = null;
1806
+ posProperty = this.containers[innermostIndex].floating ? "left" : "top";
1807
+ sizeProperty = this.containers[innermostIndex].floating ? "width" : "height";
1808
+ base = this.positionAbs[posProperty] + this.offset.click[posProperty];
1809
+ for (j = this.items.length - 1; j >= 0; j--) {
1810
+ if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
1811
+ continue;
1812
+ }
1813
+ if(this.items[j].item[0] === this.currentItem[0]) {
1814
+ continue;
1815
+ }
1816
+ cur = this.items[j].item.offset()[posProperty];
1817
+ nearBottom = false;
1818
+ if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
1819
+ nearBottom = true;
1820
+ cur += this.items[j][sizeProperty];
1821
+ }
1822
+
1823
+ if(Math.abs(cur - base) < dist) {
1824
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
1825
+ this.direction = nearBottom ? "up": "down";
1826
+ }
1827
+ }
1828
+
1829
+ //Check if dropOnEmpty is enabled
1830
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
1831
+ return;
1832
+ }
1833
+
1834
+ this.currentContainer = this.containers[innermostIndex];
1835
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
1836
+ this._trigger("change", event, this._uiHash());
1837
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
1838
+
1839
+ //Update the placeholder
1840
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
1841
+
1842
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
1843
+ this.containers[innermostIndex].containerCache.over = 1;
1844
+ }
1845
+
1846
+
1847
+ },
1848
+
1849
+ _createHelper: function(event) {
1850
+
1851
+ var o = this.options,
1852
+ helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
1853
+
1854
+ //Add the helper to the DOM if that didn't happen already
1855
+ if(!helper.parents("body").length) {
1856
+ $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
1857
+ }
1858
+
1859
+ if(helper[0] === this.currentItem[0]) {
1860
+ 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") };
1861
+ }
1862
+
1863
+ if(!helper[0].style.width || o.forceHelperSize) {
1864
+ helper.width(this.currentItem.width());
1865
+ }
1866
+ if(!helper[0].style.height || o.forceHelperSize) {
1867
+ helper.height(this.currentItem.height());
1868
+ }
1869
+
1870
+ return helper;
1871
+
1872
+ },
1873
+
1874
+ _adjustOffsetFromHelper: function(obj) {
1875
+ if (typeof obj === "string") {
1876
+ obj = obj.split(" ");
1877
+ }
1878
+ if ($.isArray(obj)) {
1879
+ obj = {left: +obj[0], top: +obj[1] || 0};
1880
+ }
1881
+ if ("left" in obj) {
1882
+ this.offset.click.left = obj.left + this.margins.left;
1883
+ }
1884
+ if ("right" in obj) {
1885
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1886
+ }
1887
+ if ("top" in obj) {
1888
+ this.offset.click.top = obj.top + this.margins.top;
1889
+ }
1890
+ if ("bottom" in obj) {
1891
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1892
+ }
1893
+ },
1894
+
1895
+ _getParentOffset: function() {
1896
+
1897
+
1898
+ //Get the offsetParent and cache its position
1899
+ this.offsetParent = this.helper.offsetParent();
1900
+ var po = this.offsetParent.offset();
1901
+
1902
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
1903
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1904
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1905
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1906
+ if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1907
+ po.left += this.scrollParent.scrollLeft();
1908
+ po.top += this.scrollParent.scrollTop();
1909
+ }
1910
+
1911
+ // This needs to be actually done for all browsers, since pageX/pageY includes this information
1912
+ // with an ugly IE fix
1913
+ if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1914
+ po = { top: 0, left: 0 };
1915
+ }
1916
+
1917
+ return {
1918
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1919
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1920
+ };
1921
+
1922
+ },
1923
+
1924
+ _getRelativeOffset: function() {
1925
+
1926
+ if(this.cssPosition === "relative") {
1927
+ var p = this.currentItem.position();
1928
+ return {
1929
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1930
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1931
+ };
1932
+ } else {
1933
+ return { top: 0, left: 0 };
1934
+ }
1935
+
1936
+ },
1937
+
1938
+ _cacheMargins: function() {
1939
+ this.margins = {
1940
+ left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
1941
+ top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
1942
+ };
1943
+ },
1944
+
1945
+ _cacheHelperProportions: function() {
1946
+ this.helperProportions = {
1947
+ width: this.helper.outerWidth(),
1948
+ height: this.helper.outerHeight()
1949
+ };
1950
+ },
1951
+
1952
+ _setContainment: function() {
1953
+
1954
+ var ce, co, over,
1955
+ o = this.options;
1956
+ if(o.containment === "parent") {
1957
+ o.containment = this.helper[0].parentNode;
1958
+ }
1959
+ if(o.containment === "document" || o.containment === "window") {
1960
+ this.containment = [
1961
+ 0 - this.offset.relative.left - this.offset.parent.left,
1962
+ 0 - this.offset.relative.top - this.offset.parent.top,
1963
+ $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1964
+ ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1965
+ ];
1966
+ }
1967
+
1968
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
1969
+ ce = $(o.containment)[0];
1970
+ co = $(o.containment).offset();
1971
+ over = ($(ce).css("overflow") !== "hidden");
1972
+
1973
+ this.containment = [
1974
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
1975
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
1976
+ 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,
1977
+ 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
1978
+ ];
1979
+ }
1980
+
1981
+ },
1982
+
1983
+ _convertPositionTo: function(d, pos) {
1984
+
1985
+ if(!pos) {
1986
+ pos = this.position;
1987
+ }
1988
+ var mod = d === "absolute" ? 1 : -1,
1989
+ scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1990
+ scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1991
+
1992
+ return {
1993
+ top: (
1994
+ pos.top + // The absolute mouse position
1995
+ this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1996
+ this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1997
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1998
+ ),
1999
+ left: (
2000
+ pos.left + // The absolute mouse position
2001
+ this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
2002
+ this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
2003
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
2004
+ )
2005
+ };
2006
+
2007
+ },
2008
+
2009
+ _generatePosition: function(event) {
2010
+
2011
+ var top, left,
2012
+ o = this.options,
2013
+ pageX = event.pageX,
2014
+ pageY = event.pageY,
2015
+ 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);
2016
+
2017
+ // This is another very weird special case that only happens for relative elements:
2018
+ // 1. If the css position is relative
2019
+ // 2. and the scroll parent is the document or similar to the offset parent
2020
+ // we have to refresh the relative offset during the scroll so there are no jumps
2021
+ if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
2022
+ this.offset.relative = this._getRelativeOffset();
2023
+ }
2024
+
2025
+ /*
2026
+ * - Position constraining -
2027
+ * Constrain the position to a mix of grid, containment.
2028
+ */
2029
+
2030
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
2031
+
2032
+ if(this.containment) {
2033
+ if(event.pageX - this.offset.click.left < this.containment[0]) {
2034
+ pageX = this.containment[0] + this.offset.click.left;
2035
+ }
2036
+ if(event.pageY - this.offset.click.top < this.containment[1]) {
2037
+ pageY = this.containment[1] + this.offset.click.top;
2038
+ }
2039
+ if(event.pageX - this.offset.click.left > this.containment[2]) {
2040
+ pageX = this.containment[2] + this.offset.click.left;
2041
+ }
2042
+ if(event.pageY - this.offset.click.top > this.containment[3]) {
2043
+ pageY = this.containment[3] + this.offset.click.top;
2044
+ }
2045
+ }
2046
+
2047
+ if(o.grid) {
2048
+ top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
2049
+ 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;
2050
+
2051
+ left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
2052
+ 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;
2053
+ }
2054
+
2055
+ }
2056
+
2057
+ return {
2058
+ top: (
2059
+ pageY - // The absolute mouse position
2060
+ this.offset.click.top - // Click offset (relative to the element)
2061
+ this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
2062
+ this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
2063
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
2064
+ ),
2065
+ left: (
2066
+ pageX - // The absolute mouse position
2067
+ this.offset.click.left - // Click offset (relative to the element)
2068
+ this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
2069
+ this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
2070
+ ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
2071
+ )
2072
+ };
2073
+
2074
+ },
2075
+
2076
+ _rearrange: function(event, i, a, hardRefresh) {
2077
+
2078
+ 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));
2079
+
2080
+ //Various things done here to improve the performance:
2081
+ // 1. we create a setTimeout, that calls refreshPositions
2082
+ // 2. on the instance, we have a counter variable, that get's higher after every append
2083
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
2084
+ // 4. this lets only the last addition to the timeout stack through
2085
+ this.counter = this.counter ? ++this.counter : 1;
2086
+ var counter = this.counter;
2087
+
2088
+ this._delay(function() {
2089
+ if(counter === this.counter) {
2090
+ this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
2091
+ }
2092
+ });
2093
+
2094
+ },
2095
+
2096
+ _clear: function(event, noPropagation) {
2097
+
2098
+ this.reverting = false;
2099
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
2100
+ // everything else normalized again
2101
+ var i,
2102
+ delayedTriggers = [];
2103
+
2104
+ // We first have to update the dom position of the actual currentItem
2105
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
2106
+ if(!this._noFinalSort && this.currentItem.parent().length) {
2107
+ this.placeholder.before(this.currentItem);
2108
+ }
2109
+ this._noFinalSort = null;
2110
+
2111
+ if(this.helper[0] === this.currentItem[0]) {
2112
+ for(i in this._storedCSS) {
2113
+ if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
2114
+ this._storedCSS[i] = "";
2115
+ }
2116
+ }
2117
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2118
+ } else {
2119
+ this.currentItem.show();
2120
+ }
2121
+
2122
+ if(this.fromOutside && !noPropagation) {
2123
+ delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
2124
+ }
2125
+ if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
2126
+ delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
2127
+ }
2128
+
2129
+ // Check if the items Container has Changed and trigger appropriate
2130
+ // events.
2131
+ if (this !== this.currentContainer) {
2132
+ if(!noPropagation) {
2133
+ delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
2134
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
2135
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
2136
+ }
2137
+ }
2138
+
2139
+
2140
+ //Post events to containers
2141
+ for (i = this.containers.length - 1; i >= 0; i--){
2142
+ if(!noPropagation) {
2143
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
2144
+ }
2145
+ if(this.containers[i].containerCache.over) {
2146
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
2147
+ this.containers[i].containerCache.over = 0;
2148
+ }
2149
+ }
2150
+
2151
+ //Do what was originally in plugins
2152
+ if(this._storedCursor) {
2153
+ $("body").css("cursor", this._storedCursor);
2154
+ }
2155
+ if(this._storedOpacity) {
2156
+ this.helper.css("opacity", this._storedOpacity);
2157
+ }
2158
+ if(this._storedZIndex) {
2159
+ this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
2160
+ }
2161
+
2162
+ this.dragging = false;
2163
+ if(this.cancelHelperRemoval) {
2164
+ if(!noPropagation) {
2165
+ this._trigger("beforeStop", event, this._uiHash());
2166
+ for (i=0; i < delayedTriggers.length; i++) {
2167
+ delayedTriggers[i].call(this, event);
2168
+ } //Trigger all delayed events
2169
+ this._trigger("stop", event, this._uiHash());
2170
+ }
2171
+
2172
+ this.fromOutside = false;
2173
+ return false;
2174
+ }
2175
+
2176
+ if(!noPropagation) {
2177
+ this._trigger("beforeStop", event, this._uiHash());
2178
+ }
2179
+
2180
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
2181
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
2182
+
2183
+ if(this.helper[0] !== this.currentItem[0]) {
2184
+ this.helper.remove();
2185
+ }
2186
+ this.helper = null;
2187
+
2188
+ if(!noPropagation) {
2189
+ for (i=0; i < delayedTriggers.length; i++) {
2190
+ delayedTriggers[i].call(this, event);
2191
+ } //Trigger all delayed events
2192
+ this._trigger("stop", event, this._uiHash());
2193
+ }
2194
+
2195
+ this.fromOutside = false;
2196
+ return true;
2197
+
2198
+ },
2199
+
2200
+ _trigger: function() {
2201
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
2202
+ this.cancel();
2203
+ }
2204
+ },
2205
+
2206
+ _uiHash: function(_inst) {
2207
+ var inst = _inst || this;
2208
+ return {
2209
+ helper: inst.helper,
2210
+ placeholder: inst.placeholder || $([]),
2211
+ position: inst.position,
2212
+ originalPosition: inst.originalPosition,
2213
+ offset: inst.positionAbs,
2214
+ item: inst.currentItem,
2215
+ sender: _inst ? _inst.element : null
2216
+ };
2217
+ }
2218
+
2219
+ });
2220
+
2221
+ })(jQuery);