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