flms 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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);