pager-jrails 0.3.20080506

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.
@@ -0,0 +1,2158 @@
1
+ /*
2
+ * jQuery UI @VERSION
3
+ *
4
+ * Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI
9
+ *
10
+ * $Date: 2008-04-01 07:23:47 -0600 (Tue, 01 Apr 2008) $
11
+ * $Rev: 5174 $
12
+ */
13
+ ;(function($) {
14
+
15
+ //If the UI scope is not available, add it
16
+ $.ui = $.ui || {};
17
+
18
+ //Add methods that are vital for all mouse interaction stuff (plugin registering)
19
+ $.extend($.ui, {
20
+ plugin: {
21
+ add: function(module, option, set) {
22
+ var proto = $.ui[module].prototype;
23
+ for(var i in set) {
24
+ proto.plugins[i] = proto.plugins[i] || [];
25
+ proto.plugins[i].push([option, set[i]]);
26
+ }
27
+ },
28
+ call: function(instance, name, arguments) {
29
+ var set = instance.plugins[name]; if(!set) return;
30
+ for (var i = 0; i < set.length; i++) {
31
+ if (instance.options[set[i][0]]) set[i][1].apply(instance.element, arguments);
32
+ }
33
+ }
34
+ },
35
+ cssCache: {},
36
+ css: function(name) {
37
+ if ($.ui.cssCache[name]) return $.ui.cssCache[name];
38
+ var tmp = $('<div class="ui-resizable-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
39
+
40
+ //if (!$.browser.safari)
41
+ //tmp.appendTo('body');
42
+
43
+ //Opera and Safari set width and height to 0px instead of auto
44
+ //Safari returns rgba(0,0,0,0) when bgcolor is not set
45
+ $.ui.cssCache[name] = !!(
46
+ (!/auto|default/.test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
47
+ !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
48
+ );
49
+ try { $('body').get(0).removeChild(tmp.get(0)); } catch(e){}
50
+ return $.ui.cssCache[name];
51
+ },
52
+ disableSelection: function(e) {
53
+ e.unselectable = "on";
54
+ e.onselectstart = function() { return false; };
55
+ if (e.style) e.style.MozUserSelect = "none";
56
+ },
57
+ enableSelection: function(e) {
58
+ e.unselectable = "off";
59
+ e.onselectstart = function() { return true; };
60
+ if (e.style) e.style.MozUserSelect = "";
61
+ },
62
+ hasScroll: function(e, a) {
63
+ var scroll = /top/.test(a||"top") ? 'scrollTop' : 'scrollLeft', has = false;
64
+ if (e[scroll] > 0) return true; e[scroll] = 1;
65
+ has = e[scroll] > 0 ? true : false; e[scroll] = 0;
66
+ return has;
67
+ }
68
+ });
69
+
70
+ /******* fn scope modifications ********/
71
+
72
+ $.each( ['Left', 'Top'], function(i, name) {
73
+ if(!$.fn['scroll'+name]) $.fn['scroll'+name] = function(v) {
74
+ return v != undefined ?
75
+ this.each(function() { this == window || this == document ? window.scrollTo(name == 'Left' ? v : $(window)['scrollLeft'](), name == 'Top' ? v : $(window)['scrollTop']()) : this['scroll'+name] = v; }) :
76
+ this[0] == window || this[0] == document ? self[(name == 'Left' ? 'pageXOffset' : 'pageYOffset')] || $.boxModel && document.documentElement['scroll'+name] || document.body['scroll'+name] : this[0][ 'scroll' + name ];
77
+ };
78
+ });
79
+
80
+ var _remove = $.fn.remove;
81
+ $.fn.extend({
82
+ position: function() {
83
+ var offset = this.offset();
84
+ var offsetParent = this.offsetParent();
85
+ var parentOffset = offsetParent.offset();
86
+
87
+ return {
88
+ top: offset.top - num(this[0], 'marginTop') - parentOffset.top - num(offsetParent, 'borderTopWidth'),
89
+ left: offset.left - num(this[0], 'marginLeft') - parentOffset.left - num(offsetParent, 'borderLeftWidth')
90
+ };
91
+ },
92
+ offsetParent: function() {
93
+ var offsetParent = this[0].offsetParent;
94
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
95
+ offsetParent = offsetParent.offsetParent;
96
+ return $(offsetParent);
97
+ },
98
+ mouseInteraction: function(o) {
99
+ return this.each(function() {
100
+ new $.ui.mouseInteraction(this, o);
101
+ });
102
+ },
103
+ removeMouseInteraction: function(o) {
104
+ return this.each(function() {
105
+ if($.data(this, "ui-mouse"))
106
+ $.data(this, "ui-mouse").destroy();
107
+ });
108
+ },
109
+ remove: function() {
110
+ jQuery("*", this).add(this).trigger("remove");
111
+ return _remove.apply(this, arguments );
112
+ }
113
+ });
114
+
115
+ function num(el, prop) {
116
+ return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
117
+ };
118
+
119
+
120
+ /********** Mouse Interaction Plugin *********/
121
+
122
+ $.ui.mouseInteraction = function(element, options) {
123
+
124
+ var self = this;
125
+ this.element = element;
126
+
127
+ $.data(this.element, "ui-mouse", this);
128
+ this.options = $.extend({}, options);
129
+
130
+ $(element).bind('mousedown.draggable', function() { return self.click.apply(self, arguments); });
131
+ if($.browser.msie) $(element).attr('unselectable', 'on'); //Prevent text selection in IE
132
+
133
+ // prevent draggable-options-delay bug #2553
134
+ $(element).mouseup(function() {
135
+ if(self.timer) clearInterval(self.timer);
136
+ });
137
+ };
138
+
139
+ $.extend($.ui.mouseInteraction.prototype, {
140
+
141
+ destroy: function() { $(this.element).unbind('mousedown.draggable'); },
142
+ trigger: function() { return this.click.apply(this, arguments); },
143
+ click: function(e) {
144
+
145
+ if(
146
+ e.which != 1 //only left click starts dragging
147
+ || $.inArray(e.target.nodeName.toLowerCase(), this.options.dragPrevention || []) != -1 // Prevent execution on defined elements
148
+ || (this.options.condition && !this.options.condition.apply(this.options.executor || this, [e, this.element])) //Prevent execution on condition
149
+ ) return true;
150
+
151
+ var self = this;
152
+ var initialize = function() {
153
+ self._MP = { left: e.pageX, top: e.pageY }; // Store the click mouse position
154
+ $(document).bind('mouseup.draggable', function() { return self.stop.apply(self, arguments); });
155
+ $(document).bind('mousemove.draggable', function() { return self.drag.apply(self, arguments); });
156
+
157
+ if(!self.initalized && Math.abs(self._MP.left-e.pageX) >= self.options.distance || Math.abs(self._MP.top-e.pageY) >= self.options.distance) {
158
+ if(self.options.start) self.options.start.call(self.options.executor || self, e, self.element);
159
+ if(self.options.drag) self.options.drag.call(self.options.executor || self, e, this.element); //This is actually not correct, but expected
160
+ self.initialized = true;
161
+ }
162
+ };
163
+
164
+ if(this.options.delay) {
165
+ if(this.timer) clearInterval(this.timer);
166
+ this.timer = setTimeout(initialize, this.options.delay);
167
+ } else {
168
+ initialize();
169
+ }
170
+
171
+ return false;
172
+
173
+ },
174
+ stop: function(e) {
175
+
176
+ var o = this.options;
177
+ if(!this.initialized) return $(document).unbind('mouseup.draggable').unbind('mousemove.draggable');
178
+
179
+ if(this.options.stop) this.options.stop.call(this.options.executor || this, e, this.element);
180
+ $(document).unbind('mouseup.draggable').unbind('mousemove.draggable');
181
+ this.initialized = false;
182
+ return false;
183
+
184
+ },
185
+ drag: function(e) {
186
+
187
+ var o = this.options;
188
+ if ($.browser.msie && !e.button) return this.stop.apply(this, [e]); // IE mouseup check
189
+
190
+ if(!this.initialized && (Math.abs(this._MP.left-e.pageX) >= o.distance || Math.abs(this._MP.top-e.pageY) >= o.distance)) {
191
+ if(this.options.start) this.options.start.call(this.options.executor || this, e, this.element);
192
+ this.initialized = true;
193
+ } else {
194
+ if(!this.initialized) return false;
195
+ }
196
+
197
+ if(o.drag) o.drag.call(this.options.executor || this, e, this.element);
198
+ return false;
199
+
200
+ }
201
+ });
202
+
203
+ })(jQuery);
204
+
205
+ /*
206
+ * jQuery UI Draggable
207
+ *
208
+ * Copyright (c) 2008 Paul Bakaus
209
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
210
+ * and GPL (GPL-LICENSE.txt) licenses.
211
+ *
212
+ * http://docs.jquery.com/UI/Draggables
213
+ *
214
+ * Depends:
215
+ * ui.base.js
216
+ *
217
+ * Revision: $Id: ui.draggable.js 5194 2008-04-04 12:30:10Z paul.bakaus $
218
+ */
219
+ ;(function($) {
220
+
221
+ $.fn.extend({
222
+ draggable: function(options) {
223
+ var args = Array.prototype.slice.call(arguments, 1);
224
+
225
+ return this.each(function() {
226
+ if (typeof options == "string") {
227
+ var drag = $.data(this, "draggable");
228
+ if(drag) drag[options].apply(drag, args);
229
+
230
+ } else if(!$.data(this, "draggable"))
231
+ new $.ui.draggable(this, options);
232
+ });
233
+ }
234
+ });
235
+
236
+ $.ui.draggable = function(element, options) {
237
+ //Initialize needed constants
238
+ var self = this;
239
+
240
+ this.element = $(element);
241
+
242
+ $.data(element, "draggable", this);
243
+ this.element.addClass("ui-draggable");
244
+
245
+ //Prepare the passed options
246
+ this.options = $.extend({}, options);
247
+ var o = this.options;
248
+ $.extend(o, {
249
+ helper: o.ghosting == true ? 'clone' : (o.helper || 'original'),
250
+ handle : o.handle ? ($(o.handle, element)[0] ? $(o.handle, element) : this.element) : this.element,
251
+ appendTo: o.appendTo || 'parent'
252
+ });
253
+
254
+ $(element).bind("setData.draggable", function(event, key, value){
255
+ self.options[key] = value;
256
+ }).bind("getData.draggable", function(event, key){
257
+ return self.options[key];
258
+ });
259
+
260
+ //Initialize mouse events for interaction
261
+ $(o.handle).mouseInteraction({
262
+ executor: this,
263
+ delay: o.delay,
264
+ distance: o.distance || 1,
265
+ dragPrevention: o.cancel || o.cancel === '' ? o.cancel.toLowerCase().split(',') : ['input','textarea','button','select','option'],
266
+ start: this.start,
267
+ stop: this.stop,
268
+ drag: this.drag,
269
+ condition: function(e) { return !(e.target.className.indexOf("ui-resizable-handle") != -1 || this.options.disabled); }
270
+ });
271
+
272
+ //Position the node
273
+ if(o.helper == 'original' && (this.element.css('position') == 'static' || this.element.css('position') == ''))
274
+ this.element.css('position', 'relative');
275
+
276
+ //Prepare cursorAt
277
+ if(o.cursorAt && o.cursorAt.constructor == Array)
278
+ o.cursorAt = { left: o.cursorAt[0], top: o.cursorAt[1] };
279
+
280
+ };
281
+
282
+ $.extend($.ui.draggable.prototype, {
283
+ plugins: {},
284
+ ui: function(e) {
285
+ return {
286
+ helper: this.helper,
287
+ position: this.position,
288
+ absolutePosition: this.positionAbs,
289
+ instance: this,
290
+ options: this.options,
291
+ element: this.element
292
+ };
293
+ },
294
+ propagate: function(n,e) {
295
+ $.ui.plugin.call(this, n, [e, this.ui()]);
296
+ return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [e, this.ui()], this.options[n]);
297
+ },
298
+ destroy: function() {
299
+ if(!$.data(this.element[0], 'draggable')) return;
300
+ this.options.handle.removeMouseInteraction();
301
+ this.element
302
+ .removeClass("ui-draggable ui-draggable-disabled")
303
+ .removeData("draggable")
304
+ .unbind(".draggable");
305
+ },
306
+ enable: function() {
307
+ this.element.removeClass("ui-draggable-disabled");
308
+ this.options.disabled = false;
309
+ },
310
+ disable: function() {
311
+ this.element.addClass("ui-draggable-disabled");
312
+ this.options.disabled = true;
313
+ },
314
+ setContrains: function(minLeft,maxLeft,minTop,maxTop) {
315
+ this.minLeft = minLeft; this.maxLeft = maxLeft;
316
+ this.minTop = minTop; this.maxTop = maxTop;
317
+ this.constrainsSet = true;
318
+ },
319
+ checkConstrains: function() {
320
+ if(!this.constrainsSet) return;
321
+ if(this.position.left < this.minLeft) this.position.left = this.minLeft;
322
+ if(this.position.left > this.maxLeft - this.helperProportions.width) this.position.left = this.maxLeft - this.helperProportions.width;
323
+ if(this.position.top < this.minTop) this.position.top = this.minTop;
324
+ if(this.position.top > this.maxTop - this.helperProportions.height) this.position.top = this.maxTop - this.helperProportions.height;
325
+ },
326
+ recallOffset: function(e) {
327
+
328
+ var elementPosition = { left: this.elementOffset.left - this.offsetParentOffset.left, top: this.elementOffset.top - this.offsetParentOffset.top };
329
+ var r = this.helper.css('position') == 'relative';
330
+
331
+ //Generate the original position
332
+ this.originalPosition = {
333
+ left: (r ? parseInt(this.helper.css('left'),10) || 0 : elementPosition.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft)),
334
+ top: (r ? parseInt(this.helper.css('top'),10) || 0 : elementPosition.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop))
335
+ };
336
+
337
+ //Generate a flexible offset that will later be subtracted from e.pageX/Y
338
+ this.offset = {left: this._pageX - this.originalPosition.left, top: this._pageY - this.originalPosition.top };
339
+
340
+ },
341
+ start: function(e) {
342
+ var o = this.options;
343
+ if($.ui.ddmanager) $.ui.ddmanager.current = this;
344
+
345
+ //Create and append the visible helper
346
+ this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e])) : (o.helper == 'clone' ? this.element.clone().appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)) : this.element);
347
+ if(this.helper[0] != this.element[0]) this.helper.css('position', 'absolute');
348
+ if(!this.helper.parents('body').length) this.helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
349
+
350
+
351
+ //Find out the next positioned parent
352
+ this.offsetParent = (function(cp) {
353
+ while(cp) {
354
+ if(cp.style && (/(absolute|relative|fixed)/).test($.css(cp,'position'))) return $(cp);
355
+ cp = cp.parentNode ? cp.parentNode : null;
356
+ }; return $("body");
357
+ })(this.helper[0].parentNode);
358
+
359
+ //Prepare variables for position generation
360
+ this.elementOffset = this.element.offset();
361
+ this.offsetParentOffset = this.offsetParent.offset();
362
+ var elementPosition = { left: this.elementOffset.left - this.offsetParentOffset.left, top: this.elementOffset.top - this.offsetParentOffset.top };
363
+ this._pageX = e.pageX; this._pageY = e.pageY;
364
+ this.clickOffset = { left: e.pageX - this.elementOffset.left, top: e.pageY - this.elementOffset.top };
365
+ var r = this.helper.css('position') == 'relative';
366
+
367
+ //Generate the original position
368
+ this.originalPosition = {
369
+ left: (r ? parseInt(this.helper.css('left'),10) || 0 : elementPosition.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft)),
370
+ top: (r ? parseInt(this.helper.css('top'),10) || 0 : elementPosition.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop))
371
+ };
372
+
373
+ //If we have a fixed element, we must subtract the scroll offset again
374
+ if(this.element.css('position') == 'fixed') {
375
+ this.originalPosition.top -= this.offsetParent[0] == document.body ? $(document).scrollTop() : this.offsetParent[0].scrollTop;
376
+ this.originalPosition.left -= this.offsetParent[0] == document.body ? $(document).scrollLeft() : this.offsetParent[0].scrollLeft;
377
+ }
378
+
379
+ //Generate a flexible offset that will later be subtracted from e.pageX/Y
380
+ this.offset = {left: e.pageX - this.originalPosition.left, top: e.pageY - this.originalPosition.top };
381
+
382
+ //Substract margins
383
+ if(this.element[0] != this.helper[0]) {
384
+ this.offset.left += parseInt(this.element.css('marginLeft'),10) || 0;
385
+ this.offset.top += parseInt(this.element.css('marginTop'),10) || 0;
386
+ }
387
+
388
+ //Call plugins and callbacks
389
+ this.propagate("start", e);
390
+
391
+ this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() };
392
+ if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);
393
+
394
+ //If we have something in cursorAt, we'll use it
395
+ if(o.cursorAt) {
396
+ if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) {
397
+ this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
398
+ this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
399
+ }
400
+ if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) {
401
+ this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
402
+ this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
403
+ }
404
+ }
405
+
406
+ return false;
407
+
408
+ },
409
+ clear: function() {
410
+ if($.ui.ddmanager) $.ui.ddmanager.current = null;
411
+ this.helper = null;
412
+ },
413
+ stop: function(e) {
414
+
415
+ //If we are using droppables, inform the manager about the drop
416
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
417
+ $.ui.ddmanager.drop(this, e);
418
+
419
+ //Call plugins and trigger callbacks
420
+ this.propagate("stop", e);
421
+
422
+ if(this.cancelHelperRemoval) return false;
423
+ if(this.options.helper != 'original') this.helper.remove();
424
+ this.clear();
425
+
426
+ return false;
427
+ },
428
+ drag: function(e) {
429
+
430
+ //Compute the helpers position
431
+ this.position = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left };
432
+ this.positionAbs = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top };
433
+
434
+ //Call plugins and callbacks
435
+ this.checkConstrains();
436
+ this.position = this.propagate("drag", e) || this.position;
437
+ this.checkConstrains();
438
+
439
+ $(this.helper).css({ left: this.position.left+'px', top: this.position.top+'px' }); // Stick the helper to the cursor
440
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);
441
+ return false;
442
+
443
+ }
444
+ });
445
+
446
+ /*
447
+ * Draggable Extensions
448
+ */
449
+
450
+ $.ui.plugin.add("draggable", "cursor", {
451
+ start: function(e, ui) {
452
+ var t = $('body');
453
+ if (t.css("cursor")) ui.options._cursor = t.css("cursor");
454
+ t.css("cursor", ui.options.cursor);
455
+ },
456
+ stop: function(e, ui) {
457
+ if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
458
+ }
459
+ });
460
+
461
+ $.ui.plugin.add("draggable", "zIndex", {
462
+ start: function(e, ui) {
463
+ var t = $(ui.helper);
464
+ if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
465
+ t.css('zIndex', ui.options.zIndex);
466
+ },
467
+ stop: function(e, ui) {
468
+ if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
469
+ }
470
+ });
471
+
472
+ $.ui.plugin.add("draggable", "opacity", {
473
+ start: function(e, ui) {
474
+ var t = $(ui.helper);
475
+ if(t.css("opacity")) ui.options._opacity = t.css("opacity");
476
+ t.css('opacity', ui.options.opacity);
477
+ },
478
+ stop: function(e, ui) {
479
+ if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
480
+ }
481
+ });
482
+
483
+
484
+ $.ui.plugin.add("draggable", "revert", {
485
+ stop: function(e, ui) {
486
+ var self = ui.instance, helper = $(self.helper);
487
+ self.cancelHelperRemoval = true;
488
+
489
+ $(ui.helper).animate({ left: self.originalPosition.left, top: self.originalPosition.top }, parseInt(ui.options.revert, 10) || 500, function() {
490
+ if(ui.options.helper != 'original') helper.remove();
491
+ if (!helper) self.clear();
492
+ });
493
+ }
494
+ });
495
+
496
+ $.ui.plugin.add("draggable", "iframeFix", {
497
+ start: function(e, ui) {
498
+
499
+ var o = ui.options;
500
+ if(ui.instance.slowMode) return; // Make clones on top of iframes (only if we are not in slowMode)
501
+
502
+ if(o.iframeFix.constructor == Array) {
503
+ for(var i=0;i<o.iframeFix.length;i++) {
504
+ var co = $(o.iframeFix[i]).offset({ border: false });
505
+ $('<div class="DragDropIframeFix"" style="background: #fff;"></div>').css("width", $(o.iframeFix[i])[0].offsetWidth+"px").css("height", $(o.iframeFix[i])[0].offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body");
506
+ }
507
+ } else {
508
+ $("iframe").each(function() {
509
+ var co = $(this).offset({ border: false });
510
+ $('<div class="DragDropIframeFix" style="background: #fff;"></div>').css("width", this.offsetWidth+"px").css("height", this.offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body");
511
+ });
512
+ }
513
+
514
+ },
515
+ stop: function(e, ui) {
516
+ if(ui.options.iframeFix) $("div.DragDropIframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
517
+ }
518
+ });
519
+
520
+ $.ui.plugin.add("draggable", "containment", {
521
+ start: function(e, ui) {
522
+
523
+ var o = ui.options;
524
+ var self = ui.instance;
525
+ if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return;
526
+ if(!o._containment) o._containment = o.containment;
527
+
528
+ if(o._containment == 'parent') o._containment = this[0].parentNode;
529
+ if(o._containment == 'document') {
530
+ o.containment = [
531
+ 0,
532
+ 0,
533
+ $(document).width(),
534
+ ($(document).height() || document.body.parentNode.scrollHeight)
535
+ ];
536
+ } else { //I'm a node, so compute top/left/right/bottom
537
+
538
+ var ce = $(o._containment)[0];
539
+ var co = $(o._containment).offset();
540
+
541
+ o.containment = [
542
+ co.left,
543
+ co.top,
544
+ co.left+(ce.offsetWidth || ce.scrollWidth),
545
+ co.top+(ce.offsetHeight || ce.scrollHeight)
546
+ ];
547
+ }
548
+
549
+ var c = o.containment;
550
+ ui.instance.setContrains(
551
+ c[0] - (self.offset.left - self.clickOffset.left), //min left
552
+ c[2] - (self.offset.left - self.clickOffset.left), //max left
553
+ c[1] - (self.offset.top - self.clickOffset.top), //min top
554
+ c[3] - (self.offset.top - self.clickOffset.top) //max top
555
+ );
556
+
557
+ }
558
+ });
559
+
560
+ $.ui.plugin.add("draggable", "grid", {
561
+ drag: function(e, ui) {
562
+ var o = ui.options;
563
+ var newLeft = ui.instance.originalPosition.left + Math.round((e.pageX - ui.instance._pageX) / o.grid[0]) * o.grid[0];
564
+ var newTop = ui.instance.originalPosition.top + Math.round((e.pageY - ui.instance._pageY) / o.grid[1]) * o.grid[1];
565
+
566
+ ui.instance.position.left = newLeft;
567
+ ui.instance.position.top = newTop;
568
+
569
+ }
570
+ });
571
+
572
+ $.ui.plugin.add("draggable", "axis", {
573
+ drag: function(e, ui) {
574
+ var o = ui.options;
575
+ if(o.constraint) o.axis = o.constraint; //Legacy check
576
+ switch (o.axis) {
577
+ case 'x' : ui.instance.position.top = ui.instance.originalPosition.top; break;
578
+ case 'y' : ui.instance.position.left = ui.instance.originalPosition.left; break;
579
+ }
580
+ }
581
+ });
582
+
583
+ $.ui.plugin.add("draggable", "scroll", {
584
+ start: function(e, ui) {
585
+ var o = ui.options;
586
+ o.scrollSensitivity = o.scrollSensitivity || 20;
587
+ o.scrollSpeed = o.scrollSpeed || 20;
588
+
589
+ ui.instance.overflowY = function(el) {
590
+ do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
591
+ return $(document);
592
+ }(this);
593
+ ui.instance.overflowX = function(el) {
594
+ do { if(/auto|scroll/.test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
595
+ return $(document);
596
+ }(this);
597
+ },
598
+ drag: function(e, ui) {
599
+
600
+ var o = ui.options;
601
+ var i = ui.instance;
602
+
603
+ if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
604
+ if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
605
+ i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;
606
+ if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
607
+ i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;
608
+ } else {
609
+ //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>');
610
+ if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)
611
+ $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
612
+ if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)
613
+ $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
614
+ }
615
+
616
+ if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {
617
+ if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
618
+ i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;
619
+ if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
620
+ i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;
621
+ } else {
622
+ if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)
623
+ $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
624
+ if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
625
+ $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
626
+ }
627
+
628
+ ui.instance.recallOffset(e);
629
+
630
+ }
631
+ });
632
+
633
+ $.ui.plugin.add("draggable", "snap", {
634
+ start: function(e, ui) {
635
+
636
+ ui.instance.snapElements = [];
637
+ $(ui.options.snap === true ? '.ui-draggable' : ui.options.snap).each(function() {
638
+ var $t = $(this); var $o = $t.offset();
639
+ if(this != ui.instance.element[0]) ui.instance.snapElements.push({
640
+ item: this,
641
+ width: $t.outerWidth(),
642
+ height: $t.outerHeight(),
643
+ top: $o.top,
644
+ left: $o.left
645
+ });
646
+ });
647
+
648
+ },
649
+ drag: function(e, ui) {
650
+
651
+ var d = ui.options.snapTolerance || 20;
652
+ var x1 = ui.absolutePosition.left, x2 = x1 + ui.instance.helperProportions.width,
653
+ y1 = ui.absolutePosition.top, y2 = y1 + ui.instance.helperProportions.height;
654
+
655
+ for (var i = ui.instance.snapElements.length - 1; i >= 0; i--){
656
+
657
+ var l = ui.instance.snapElements[i].left, r = l + ui.instance.snapElements[i].width,
658
+ t = ui.instance.snapElements[i].top, b = t + ui.instance.snapElements[i].height;
659
+
660
+ //Yes, I know, this is insane ;)
661
+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) continue;
662
+
663
+ if(ui.options.snapMode != 'inner') {
664
+ var ts = Math.abs(t - y2) <= 20;
665
+ var bs = Math.abs(b - y1) <= 20;
666
+ var ls = Math.abs(l - x2) <= 20;
667
+ var rs = Math.abs(r - x1) <= 20;
668
+ if(ts) ui.position.top = t - ui.instance.offset.top + ui.instance.clickOffset.top - ui.instance.helperProportions.height;
669
+ if(bs) ui.position.top = b - ui.instance.offset.top + ui.instance.clickOffset.top;
670
+ if(ls) ui.position.left = l - ui.instance.offset.left + ui.instance.clickOffset.left - ui.instance.helperProportions.width;
671
+ if(rs) ui.position.left = r - ui.instance.offset.left + ui.instance.clickOffset.left;
672
+ }
673
+
674
+ if(ui.options.snapMode != 'outer') {
675
+ var ts = Math.abs(t - y1) <= 20;
676
+ var bs = Math.abs(b - y2) <= 20;
677
+ var ls = Math.abs(l - x1) <= 20;
678
+ var rs = Math.abs(r - x2) <= 20;
679
+ if(ts) ui.position.top = t - ui.instance.offset.top + ui.instance.clickOffset.top;
680
+ if(bs) ui.position.top = b - ui.instance.offset.top + ui.instance.clickOffset.top - ui.instance.helperProportions.height;
681
+ if(ls) ui.position.left = l - ui.instance.offset.left + ui.instance.clickOffset.left;
682
+ if(rs) ui.position.left = r - ui.instance.offset.left + ui.instance.clickOffset.left - ui.instance.helperProportions.width;
683
+ }
684
+
685
+ };
686
+ }
687
+ });
688
+
689
+ $.ui.plugin.add("draggable", "connectToSortable", {
690
+ start: function(e,ui) {
691
+ ui.instance.sortable = $.data($(ui.options.connectToSortable)[0], 'sortable');
692
+ ui.instance.sortableOffset = ui.instance.sortable.element.offset();
693
+ ui.instance.sortableOuterWidth = ui.instance.sortable.element.outerWidth();
694
+ ui.instance.sortableOuterHeight = ui.instance.sortable.element.outerHeight();
695
+ if(ui.instance.sortable.options.revert) ui.instance.sortable.shouldRevert = true;
696
+ },
697
+ stop: function(e,ui) {
698
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
699
+ var inst = ui.instance.sortable;
700
+ if(inst.isOver) {
701
+ inst.isOver = 0;
702
+ ui.instance.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
703
+ inst.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
704
+ if(inst.shouldRevert) inst.options.revert = true; //revert here
705
+ inst.stop(e);
706
+ inst.options.helper = "original";
707
+ }
708
+ },
709
+ drag: function(e,ui) {
710
+ //This is handy: We reuse the intersectsWith method for checking if the current draggable helper
711
+ //intersects with the sortable container
712
+ var inst = ui.instance.sortable;
713
+ ui.instance.position.absolute = ui.absolutePosition; //Sorry, this is an ugly API fix
714
+
715
+ if(inst.intersectsWith.call(ui.instance, {
716
+ left: ui.instance.sortableOffset.left, top: ui.instance.sortableOffset.top,
717
+ width: ui.instance.sortableOuterWidth, height: ui.instance.sortableOuterHeight
718
+ })) {
719
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
720
+ if(!inst.isOver) {
721
+ inst.isOver = 1;
722
+
723
+ //Cache the width/height of the new helper
724
+ var height = inst.options.placeholderElement ? $(inst.options.placeholderElement, $(inst.options.items, inst.element)).innerHeight() : $(inst.options.items, inst.element).innerHeight();
725
+ var width = inst.options.placeholderElement ? $(inst.options.placeholderElement, $(inst.options.items, inst.element)).innerWidth() : $(inst.options.items, inst.element).innerWidth();
726
+
727
+ //Now we fake the start of dragging for the sortable instance,
728
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
729
+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
730
+ inst.currentItem = $(this).clone().appendTo(inst.element);
731
+ inst.options.helper = function() { return ui.helper[0]; };
732
+ inst.start(e);
733
+
734
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
735
+ inst.clickOffset.top = ui.instance.clickOffset.top;
736
+ inst.clickOffset.left = ui.instance.clickOffset.left;
737
+ inst.offset.left -= ui.absolutePosition.left - inst.position.absolute.left;
738
+ inst.offset.top -= ui.absolutePosition.top - inst.position.absolute.top;
739
+
740
+ //Do a nifty little helper animation: Animate it to the portlet's size (just takes the first 'li' element in the sortable now)
741
+ inst.helperProportions = { width: width, height: height}; //We have to reset the helper proportions, because we are doing our animation there
742
+ ui.helper.animate({ height: height, width: width}, 500);
743
+ ui.instance.propagate("toSortable", e);
744
+
745
+ }
746
+
747
+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
748
+ if(inst.currentItem) inst.drag(e);
749
+
750
+ } else {
751
+
752
+ //If it doesn't intersect with the sortable, and it intersected before,
753
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
754
+ if(inst.isOver) {
755
+ inst.isOver = 0;
756
+ inst.cancelHelperRemoval = true;
757
+ inst.options.revert = false; //No revert here
758
+ inst.stop(e);
759
+ inst.options.helper = "original";
760
+
761
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
762
+ inst.currentItem.remove();
763
+ inst.placeholder.remove();
764
+
765
+ ui.helper.animate({ height: this.innerHeight(), width: this.innerWidth() }, 500);
766
+ ui.instance.propagate("fromSortable", e);
767
+ }
768
+
769
+ };
770
+ }
771
+ })
772
+
773
+ //TODO: wrapHelper
774
+
775
+ })(jQuery);
776
+
777
+ /*
778
+ * jQuery UI Droppable
779
+ *
780
+ * Copyright (c) 2008 Paul Bakaus
781
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
782
+ * and GPL (GPL-LICENSE.txt) licenses.
783
+ *
784
+ * http://docs.jquery.com/UI/Droppables
785
+ *
786
+ * Depends:
787
+ * ui.base.js
788
+ * ui.draggable.js
789
+ *
790
+ * Revision: $Id: ui.droppable.js 5198 2008-04-04 13:06:40Z paul.bakaus $
791
+ */
792
+ ;(function($) {
793
+
794
+ $.fn.extend({
795
+ droppable: function(options) {
796
+ var args = Array.prototype.slice.call(arguments, 1);
797
+
798
+ return this.each(function() {
799
+ if (typeof options == "string") {
800
+ var drop = $.data(this, "droppable");
801
+ if(drop) drop[options].apply(drop, args);
802
+
803
+ } else if(!$.data(this, "droppable"))
804
+ new $.ui.droppable(this, options);
805
+ });
806
+ }
807
+ });
808
+
809
+ $.ui.droppable = function(element, options) {
810
+
811
+ //Initialize needed constants
812
+ var instance = this;
813
+ this.element = $(element);
814
+ $.data(element, "droppable", this);
815
+ this.element.addClass("ui-droppable");
816
+
817
+ //Prepare the passed options
818
+ var o = this.options = options = $.extend({}, $.ui.droppable.defaults, options);
819
+ var accept = o.accept;
820
+ o = $.extend(o, {
821
+ accept: o.accept && o.accept.constructor == Function ? o.accept : function(d) {
822
+ return $(d).is(accept);
823
+ }
824
+ });
825
+
826
+ $(element).bind("setData.droppable", function(event, key, value){
827
+ o[key] = value;
828
+ }).bind("getData.droppable", function(event, key){
829
+ return o[key];
830
+ }).bind('remove', function() {
831
+ instance.destroy();
832
+ });
833
+
834
+ //Store the droppable's proportions
835
+ this.proportions = { width: this.element.outerWidth(), height: this.element.outerHeight() };
836
+
837
+ // Add the reference and positions to the manager
838
+ $.ui.ddmanager.droppables.push({ item: this, over: 0, out: 1 });
839
+
840
+ };
841
+
842
+ $.extend($.ui.droppable, {
843
+ defaults: {
844
+ disabled: false,
845
+ tolerance: 'intersect'
846
+ }
847
+ });
848
+
849
+ $.extend($.ui.droppable.prototype, {
850
+ plugins: {},
851
+ ui: function(c) {
852
+ return {
853
+ instance: this,
854
+ draggable: (c.currentItem || c.element),
855
+ helper: c.helper,
856
+ position: c.position,
857
+ absolutePosition: c.positionAbs,
858
+ options: this.options,
859
+ element: this.element
860
+ };
861
+ },
862
+ destroy: function() {
863
+ var drop = $.ui.ddmanager.droppables;
864
+ for ( var i = 0; i < drop.length; i++ )
865
+ if ( drop[i].item == this )
866
+ drop.splice(i, 1);
867
+
868
+ this.element
869
+ .removeClass("ui-droppable ui-droppable-disabled")
870
+ .removeData("droppable")
871
+ .unbind(".droppable");
872
+ },
873
+ enable: function() {
874
+ this.element.removeClass("ui-droppable-disabled");
875
+ this.options.disabled = false;
876
+ },
877
+ disable: function() {
878
+ this.element.addClass("ui-droppable-disabled");
879
+ this.options.disabled = true;
880
+ },
881
+ over: function(e) {
882
+
883
+ var draggable = $.ui.ddmanager.current;
884
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
885
+
886
+ if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
887
+ $.ui.plugin.call(this, 'over', [e, this.ui(draggable)]);
888
+ this.element.triggerHandler("dropover", [e, this.ui(draggable)], this.options.over);
889
+ }
890
+
891
+ },
892
+ out: function(e) {
893
+
894
+ var draggable = $.ui.ddmanager.current;
895
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
896
+
897
+ if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
898
+ $.ui.plugin.call(this, 'out', [e, this.ui(draggable)]);
899
+ this.element.triggerHandler("dropout", [e, this.ui(draggable)], this.options.out);
900
+ }
901
+
902
+ },
903
+ drop: function(e,custom) {
904
+
905
+ var draggable = custom || $.ui.ddmanager.current;
906
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
907
+
908
+ var childrenIntersection = false;
909
+ this.element.find(".ui-droppable").each(function() {
910
+ var inst = $.data(this, 'droppable');
911
+ if(inst.options.greedy && $.ui.intersect(draggable, { item: inst, offset: inst.element.offset() }, inst.options.tolerance)) {
912
+ childrenIntersection = true; return false;
913
+ }
914
+ });
915
+ if(childrenIntersection) return;
916
+
917
+ if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
918
+ $.ui.plugin.call(this, 'drop', [e, this.ui(draggable)]);
919
+ this.element.triggerHandler("drop", [e, this.ui(draggable)], this.options.drop);
920
+ }
921
+
922
+ },
923
+ activate: function(e) {
924
+
925
+ var draggable = $.ui.ddmanager.current;
926
+ $.ui.plugin.call(this, 'activate', [e, this.ui(draggable)]);
927
+ if(draggable) this.element.triggerHandler("dropactivate", [e, this.ui(draggable)], this.options.activate);
928
+
929
+ },
930
+ deactivate: function(e) {
931
+
932
+ var draggable = $.ui.ddmanager.current;
933
+ $.ui.plugin.call(this, 'deactivate', [e, this.ui(draggable)]);
934
+ if(draggable) this.element.triggerHandler("dropdeactivate", [e, this.ui(draggable)], this.options.deactivate);
935
+
936
+ }
937
+ });
938
+
939
+ $.ui.intersect = function(draggable, droppable, toleranceMode) {
940
+
941
+ if (!droppable.offset) return false;
942
+
943
+ var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
944
+ y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
945
+ var l = droppable.offset.left, r = l + droppable.item.proportions.width,
946
+ t = droppable.offset.top, b = t + droppable.item.proportions.height;
947
+
948
+ switch (toleranceMode) {
949
+ case 'fit':
950
+
951
+ if(!((y2-(draggable.helperProportions.height/2) > t && y1 < t) || (y1 < b && y2 > b) || (x2 > l && x1 < l) || (x1 < r && x2 > r))) return false;
952
+
953
+ if(y2-(draggable.helperProportions.height/2) > t && y1 < t) return 1; //Crosses top edge
954
+ if(y1 < b && y2 > b) return 2; //Crosses bottom edge
955
+ if(x2 > l && x1 < l) return 1; //Crosses left edge
956
+ if(x1 < r && x2 > r) return 2; //Crosses right edge
957
+
958
+ //return ( l < x1 && x2 < r
959
+ // && t < y1 && y2 < b);
960
+ break;
961
+ case 'intersect':
962
+ return ( l < x1 + (draggable.helperProportions.width / 2) // Right Half
963
+ && x2 - (draggable.helperProportions.width / 2) < r // Left Half
964
+ && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
965
+ && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
966
+ break;
967
+ case 'pointer':
968
+ return ( l < ((draggable.positionAbs || draggable.position.absolute).left + draggable.clickOffset.left) && ((draggable.positionAbs || draggable.position.absolute).left + draggable.clickOffset.left) < r
969
+ && t < ((draggable.positionAbs || draggable.position.absolute).top + draggable.clickOffset.top) && ((draggable.positionAbs || draggable.position.absolute).top + draggable.clickOffset.top) < b);
970
+ break;
971
+ case 'touch':
972
+ return ( (y1 >= t && y1 <= b) || // Top edge touching
973
+ (y2 >= t && y2 <= b) || // Bottom edge touching
974
+ (y1 < t && y2 > b) // Surrounded vertically
975
+ ) && (
976
+ (x1 >= l && x1 <= r) || // Left edge touching
977
+ (x2 >= l && x2 <= r) || // Right edge touching
978
+ (x1 < l && x2 > r) // Surrounded horizontally
979
+ );
980
+ break;
981
+ default:
982
+ return false;
983
+ break;
984
+ }
985
+
986
+ };
987
+
988
+ /*
989
+ This manager tracks offsets of draggables and droppables
990
+ */
991
+ $.ui.ddmanager = {
992
+ current: null,
993
+ droppables: [],
994
+ prepareOffsets: function(t, e) {
995
+
996
+ var m = $.ui.ddmanager.droppables;
997
+ var type = e ? e.type : null; // workaround for #2317
998
+ for (var i = 0; i < m.length; i++) {
999
+
1000
+ if(m[i].item.options.disabled || (t && !m[i].item.options.accept.call(m[i].item.element,(t.currentItem || t.element)))) continue;
1001
+ m[i].offset = $(m[i].item.element).offset();
1002
+ m[i].item.proportions = { width: m[i].item.element.outerWidth(), height: m[i].item.element.outerHeight() };
1003
+
1004
+ if(type == "dragstart") m[i].item.activate.call(m[i].item, e); //Activate the droppable if used directly from draggables
1005
+ }
1006
+
1007
+ },
1008
+ drop: function(draggable, e) {
1009
+
1010
+ $.each($.ui.ddmanager.droppables, function() {
1011
+
1012
+ if (!this.item.options.disabled && $.ui.intersect(draggable, this, this.item.options.tolerance))
1013
+ this.item.drop.call(this.item, e);
1014
+
1015
+ if (!this.item.options.disabled && this.item.options.accept.call(this.item.element,(draggable.currentItem || draggable.element))) {
1016
+ this.out = 1; this.over = 0;
1017
+ this.item.deactivate.call(this.item, e);
1018
+ }
1019
+
1020
+ });
1021
+
1022
+ },
1023
+ drag: function(draggable, e) {
1024
+
1025
+ //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1026
+ if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, e);
1027
+
1028
+ //Run through all droppables and check their positions based on specific tolerance options
1029
+ $.each($.ui.ddmanager.droppables, function() {
1030
+
1031
+ if(this.item.disabled || this.greedyChild) return;
1032
+ var intersects = $.ui.intersect(draggable, this, this.item.options.tolerance);
1033
+
1034
+ var c = !intersects && this.over == 1 ? 'out' : (intersects && this.over == 0 ? 'over' : null);
1035
+ if(!c) return;
1036
+
1037
+ var instance = $.data(this.item.element[0], 'droppable');
1038
+ if (instance.options.greedy) {
1039
+ this.item.element.parents('.ui-droppable:eq(0)').each(function() {
1040
+ var parent = this;
1041
+ $.each($.ui.ddmanager.droppables, function() {
1042
+ if (this.item.element[0] != parent) return;
1043
+ this[c] = 0;
1044
+ this[c == 'out' ? 'over' : 'out'] = 1;
1045
+ this.greedyChild = (c == 'over' ? 1 : 0);
1046
+ this.item[c == 'out' ? 'over' : 'out'].call(this.item, e);
1047
+ return false;
1048
+ });
1049
+ });
1050
+ }
1051
+
1052
+ this[c] = 1; this[c == 'out' ? 'over' : 'out'] = 0;
1053
+ this.item[c].call(this.item, e);
1054
+
1055
+ });
1056
+
1057
+ }
1058
+ };
1059
+
1060
+ /*
1061
+ * Droppable Extensions
1062
+ */
1063
+
1064
+ $.ui.plugin.add("droppable", "activeClass", {
1065
+ activate: function(e, ui) {
1066
+ $(this).addClass(ui.options.activeClass);
1067
+ },
1068
+ deactivate: function(e, ui) {
1069
+ $(this).removeClass(ui.options.activeClass);
1070
+ },
1071
+ drop: function(e, ui) {
1072
+ $(this).removeClass(ui.options.activeClass);
1073
+ }
1074
+ });
1075
+
1076
+ $.ui.plugin.add("droppable", "hoverClass", {
1077
+ over: function(e, ui) {
1078
+ $(this).addClass(ui.options.hoverClass);
1079
+ },
1080
+ out: function(e, ui) {
1081
+ $(this).removeClass(ui.options.hoverClass);
1082
+ },
1083
+ drop: function(e, ui) {
1084
+ $(this).removeClass(ui.options.hoverClass);
1085
+ }
1086
+ });
1087
+
1088
+ })(jQuery);
1089
+
1090
+ /*
1091
+ * jQuery UI Slider
1092
+ *
1093
+ * Copyright (c) 2008 Paul Bakaus
1094
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
1095
+ * and GPL (GPL-LICENSE.txt) licenses.
1096
+ *
1097
+ * http://docs.jquery.com/UI/Slider
1098
+ *
1099
+ * Depends:
1100
+ * ui.base.js
1101
+ *
1102
+ * Revision: $Id: ui.slider.js 5196 2008-04-04 12:52:32Z paul.bakaus $
1103
+ */
1104
+ ;(function($) {
1105
+
1106
+ $.fn.extend({
1107
+ slider: function(options) {
1108
+ var args = Array.prototype.slice.call(arguments, 1);
1109
+
1110
+ if ( options == "value" )
1111
+ return $.data(this[0], "slider").value(arguments[1]);
1112
+
1113
+ return this.each(function() {
1114
+ if (typeof options == "string") {
1115
+ var slider = $.data(this, "slider");
1116
+ if (slider) slider[options].apply(slider, args);
1117
+
1118
+ } else if(!$.data(this, "slider"))
1119
+ new $.ui.slider(this, options);
1120
+ });
1121
+ }
1122
+ });
1123
+
1124
+ $.ui.slider = function(element, options) {
1125
+
1126
+ //Initialize needed constants
1127
+ var self = this;
1128
+ this.element = $(element);
1129
+ $.data(element, "slider", this);
1130
+ this.element.addClass("ui-slider");
1131
+
1132
+ //Prepare the passed options
1133
+ this.options = $.extend({}, $.ui.slider.defaults, options);
1134
+ var o = this.options;
1135
+ $.extend(o, {
1136
+ axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'),
1137
+ max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }),
1138
+ min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 })
1139
+ });
1140
+
1141
+ //Prepare the real maxValue
1142
+ o.realMax = {
1143
+ x: o.max.x - o.min.x,
1144
+ y: o.max.y - o.min.y
1145
+ };
1146
+
1147
+ //Calculate stepping based on steps
1148
+ o.stepping = {
1149
+ x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps && o.steps.x ? o.realMax.x/o.steps.x : 0),
1150
+ y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps && o.steps.y ? o.realMax.y/o.steps.y : 0)
1151
+ };
1152
+
1153
+ $(element).bind("setData.slider", function(event, key, value){
1154
+ self.options[key] = value;
1155
+ }).bind("getData.slider", function(event, key){
1156
+ return self.options[key];
1157
+ });
1158
+
1159
+ //Initialize mouse and key events for interaction
1160
+ this.handle = $(o.handle, element);
1161
+ if (!this.handle.length) {
1162
+ self.handle = self.generated = $(o.handles || [0]).map(function() {
1163
+ var handle = $("<div/>").addClass("ui-slider-handle").appendTo(element);
1164
+ if (this.id)
1165
+ handle.attr("id", this.id);
1166
+ return handle[0];
1167
+ });
1168
+ }
1169
+ $(this.handle)
1170
+ .mouseInteraction({
1171
+ executor: this,
1172
+ delay: o.delay,
1173
+ distance: o.distance != undefined ? o.distance : 1,
1174
+ dragPrevention: o.prevention ? o.prevention.toLowerCase().split(',') : ['input','textarea','button','select','option'],
1175
+ start: this.start,
1176
+ stop: this.stop,
1177
+ drag: this.drag,
1178
+ condition: function(e, handle) {
1179
+ if(!this.disabled) {
1180
+ if(this.currentHandle) this.blur(this.currentHandle);
1181
+ this.focus(handle,1);
1182
+ return !this.disabled;
1183
+ }
1184
+ }
1185
+ })
1186
+ .wrap('<a href="javascript:void(0)" style="cursor:default;"></a>')
1187
+ .parent()
1188
+ .bind('focus', function(e) { self.focus(this.firstChild); })
1189
+ .bind('blur', function(e) { self.blur(this.firstChild); })
1190
+ .bind('keydown', function(e) {
1191
+ if(/(37|38|39|40)/.test(e.keyCode)) {
1192
+ self.moveTo({
1193
+ x: /(37|39)/.test(e.keyCode) ? (e.keyCode == 37 ? '-' : '+') + '=' + self.oneStep(1) : null,
1194
+ y: /(38|40)/.test(e.keyCode) ? (e.keyCode == 38 ? '-' : '+') + '=' + self.oneStep(2) : null
1195
+ }, this.firstChild);
1196
+ }
1197
+ })
1198
+ ;
1199
+
1200
+ //Prepare dynamic properties for later use
1201
+ this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
1202
+
1203
+ //Bind the click to the slider itself
1204
+ this.element.bind('mousedown.slider', function(e) {
1205
+ self.click.apply(self, [e]);
1206
+ self.currentHandle.data("ui-mouse").trigger(e);
1207
+ self.firstValue = self.firstValue + 1; //This is for always triggering the change event
1208
+ });
1209
+
1210
+ //Move the first handle to the startValue
1211
+ $.each(o.handles || [], function(index, handle) {
1212
+ self.moveTo(handle.start, index, true);
1213
+ });
1214
+ if (!isNaN(o.startValue))
1215
+ this.moveTo(o.startValue, 0, true);
1216
+
1217
+ //If we only have one handle, set the previous handle to this one to allow clicking before selecting the handle
1218
+ if(this.handle.length == 1) this.previousHandle = this.handle;
1219
+ if(this.handle.length == 2 && o.range) this.createRange();
1220
+
1221
+ };
1222
+
1223
+ $.extend($.ui.slider.prototype, {
1224
+ plugins: {},
1225
+ createRange: function() {
1226
+ this.rangeElement = $('<div></div>')
1227
+ .addClass('ui-slider-range')
1228
+ .css({ position: 'absolute' })
1229
+ .appendTo(this.element);
1230
+ this.updateRange();
1231
+ },
1232
+ updateRange: function() {
1233
+ var prop = this.options.axis == "vertical" ? "top" : "left";
1234
+ var size = this.options.axis == "vertical" ? "height" : "width";
1235
+ this.rangeElement.css(prop, parseInt($(this.handle[0]).css(prop),10) + this.handleSize(0, this.options.axis == "vertical" ? 2 : 1)/2);
1236
+ this.rangeElement.css(size, parseInt($(this.handle[1]).css(prop),10) - parseInt($(this.handle[0]).css(prop),10));
1237
+ },
1238
+ getRange: function() {
1239
+ return this.rangeElement ? this.convertValue(parseInt(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width"),10)) : null;
1240
+ },
1241
+ ui: function(e) {
1242
+ return {
1243
+ instance: this,
1244
+ options: this.options,
1245
+ handle: this.currentHandle,
1246
+ value: this.options.axis != "both" || !this.options.axis ? Math.round(this.value(null,this.options.axis == "vertical" ? 2 : 1)) : {
1247
+ x: Math.round(this.value(null,1)),
1248
+ y: Math.round(this.value(null,2))
1249
+ },
1250
+ range: this.getRange()
1251
+ };
1252
+ },
1253
+ propagate: function(n,e) {
1254
+ $.ui.plugin.call(this, n, [e, this.ui()]);
1255
+ this.element.triggerHandler(n == "slide" ? n : "slide"+n, [e, this.ui()], this.options[n]);
1256
+ },
1257
+ destroy: function() {
1258
+ this.element
1259
+ .removeClass("ui-slider ui-slider-disabled")
1260
+ .removeData("slider")
1261
+ .unbind(".slider");
1262
+ this.handle.removeMouseInteraction();
1263
+ this.generated && this.generated.remove();
1264
+ },
1265
+ enable: function() {
1266
+ this.element.removeClass("ui-slider-disabled");
1267
+ this.disabled = false;
1268
+ },
1269
+ disable: function() {
1270
+ this.element.addClass("ui-slider-disabled");
1271
+ this.disabled = true;
1272
+ },
1273
+ focus: function(handle,hard) {
1274
+ this.currentHandle = $(handle).addClass('ui-slider-handle-active');
1275
+ if(hard) this.currentHandle.parent()[0].focus();
1276
+ },
1277
+ blur: function(handle) {
1278
+ $(handle).removeClass('ui-slider-handle-active');
1279
+ if(this.currentHandle && this.currentHandle[0] == handle) { this.previousHandle = this.currentHandle; this.currentHandle = null; };
1280
+ },
1281
+ value: function(handle, axis) {
1282
+ if(this.handle.length == 1) this.currentHandle = this.handle;
1283
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1284
+
1285
+ var value = ((parseInt($(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle).css(axis == 1 ? "left" : "top"),10) / (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis))) * this.options.realMax[axis == 1 ? "x" : "y"]) + this.options.min[axis == 1 ? "x" : "y"];
1286
+
1287
+ var o = this.options;
1288
+ if (o.stepping[axis == 1 ? "x" : "y"]) {
1289
+ value = Math.round(value / o.stepping[axis == 1 ? "x" : "y"]) * o.stepping[axis == 1 ? "x" : "y"];
1290
+ }
1291
+ return value;
1292
+ },
1293
+ convertValue: function(value,axis) {
1294
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1295
+ return this.options.min[axis == 1 ? "x" : "y"] + (value / (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis))) * this.options.realMax[axis == 1 ? "x" : "y"];
1296
+ },
1297
+ translateValue: function(value,axis) {
1298
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1299
+ return ((value - this.options.min[axis == 1 ? "x" : "y"]) / this.options.realMax[axis == 1 ? "x" : "y"]) * (this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis));
1300
+ },
1301
+ handleSize: function(handle,axis) {
1302
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1303
+ return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[axis == 1 ? "outerWidth" : "outerHeight"]();
1304
+ },
1305
+ click: function(e) {
1306
+
1307
+ // This method is only used if:
1308
+ // - The user didn't click a handle
1309
+ // - The Slider is not disabled
1310
+ // - There is a current, or previous selected handle (otherwise we wouldn't know which one to move)
1311
+ var pointer = [e.pageX,e.pageY];
1312
+ var clickedHandle = false; this.handle.each(function() { if(this == e.target) clickedHandle = true; });
1313
+ if(clickedHandle || this.disabled || !(this.currentHandle || this.previousHandle)) return;
1314
+
1315
+ //If a previous handle was focussed, focus it again
1316
+ if(this.previousHandle) this.focus(this.previousHandle, 1);
1317
+
1318
+ //Move focussed handle to the clicked position
1319
+ this.offset = this.element.offset();
1320
+ this.moveTo({
1321
+ y: this.convertValue(e.pageY - this.offset.top - this.currentHandle.outerHeight()/2),
1322
+ x: this.convertValue(e.pageX - this.offset.left - this.currentHandle.outerWidth()/2)
1323
+ }, null, true);
1324
+ },
1325
+ start: function(e, handle) {
1326
+
1327
+ var o = this.options;
1328
+ if(!this.currentHandle) this.focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
1329
+
1330
+ this.offset = this.element.offset();
1331
+ this.handleOffset = this.currentHandle.offset();
1332
+ this.clickOffset = { top: e.pageY - this.handleOffset.top, left: e.pageX - this.handleOffset.left };
1333
+ this.firstValue = this.value();
1334
+
1335
+ this.propagate('start', e);
1336
+ return false;
1337
+
1338
+ },
1339
+ stop: function(e) {
1340
+ this.propagate('stop', e);
1341
+ if (this.firstValue != this.value())
1342
+ this.propagate('change', e);
1343
+ this.focus(this.currentHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
1344
+ return false;
1345
+ },
1346
+
1347
+ oneStep: function(axis) {
1348
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1349
+ return this.options.stepping[axis == 1 ? "x" : "y"] ? this.options.stepping[axis == 1 ? "x" : "y"] : (this.options.realMax[axis == 1 ? "x" : "y"] / this.actualSize[axis == 1 ? "width" : "height"]) * 5;
1350
+ },
1351
+
1352
+ translateRange: function(value,axis) {
1353
+ if (this.rangeElement) {
1354
+ if (this.currentHandle[0] == this.handle[0] && value >= this.translateValue(this.value(1),axis))
1355
+ value = this.translateValue(this.value(1,axis) - this.oneStep(axis), axis);
1356
+ if (this.currentHandle[0] == this.handle[1] && value <= this.translateValue(this.value(0),axis))
1357
+ value = this.translateValue(this.value(0,axis) + this.oneStep(axis));
1358
+ }
1359
+ if (this.options.handles) {
1360
+ var handle = this.options.handles[this.handleIndex()];
1361
+ if (value < this.translateValue(handle.min,axis)) {
1362
+ value = this.translateValue(handle.min,axis);
1363
+ } else if (value > this.translateValue(handle.max,axis)) {
1364
+ value = this.translateValue(handle.max,axis);
1365
+ }
1366
+ }
1367
+ return value;
1368
+ },
1369
+
1370
+ handleIndex: function() {
1371
+ return this.handle.index(this.currentHandle[0])
1372
+ },
1373
+
1374
+ translateLimits: function(value,axis) {
1375
+ if(!axis) axis = this.options.axis == "vertical" ? 2 : 1;
1376
+ if (value >= this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis))
1377
+ value = this.actualSize[axis == 1 ? "width" : "height"] - this.handleSize(null,axis);
1378
+ if (value <= 0)
1379
+ value = 0;
1380
+ return value;
1381
+ },
1382
+
1383
+ drag: function(e, handle) {
1384
+
1385
+ var o = this.options;
1386
+ var position = { top: e.pageY - this.offset.top - this.clickOffset.top, left: e.pageX - this.offset.left - this.clickOffset.left};
1387
+ if(!this.currentHandle) this.focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events
1388
+
1389
+ position.left = this.translateLimits(position.left,1);
1390
+ position.top = this.translateLimits(position.top,2);
1391
+
1392
+ if (o.stepping.x) {
1393
+ var value = this.convertValue(position.left,1);
1394
+ value = Math.round(value / o.stepping.x) * o.stepping.x;
1395
+ position.left = this.translateValue(value, 1);
1396
+ }
1397
+ if (o.stepping.y) {
1398
+ var value = this.convertValue(position.top,2);
1399
+ value = Math.round(value / o.stepping.y) * o.stepping.y;
1400
+ position.top = this.translateValue(value, 2);
1401
+ }
1402
+
1403
+ position.left = this.translateRange(position.left, 1);
1404
+ position.top = this.translateRange(position.top, 2);
1405
+
1406
+ if(o.axis != "vertical") this.currentHandle.css({ left: position.left });
1407
+ if(o.axis != "horizontal") this.currentHandle.css({ top: position.top });
1408
+
1409
+ if (this.rangeElement)
1410
+ this.updateRange();
1411
+ this.propagate('slide', e);
1412
+ return false;
1413
+ },
1414
+
1415
+ moveTo: function(value, handle, noPropagation) {
1416
+ var o = this.options;
1417
+ if (handle == undefined && !this.currentHandle && this.handle.length != 1)
1418
+ return false; //If no handle has been passed, no current handle is available and we have multiple handles, return false
1419
+ if (handle == undefined && !this.currentHandle)
1420
+ handle = 0; //If only one handle is available, use it
1421
+ if (handle != undefined)
1422
+ this.currentHandle = this.previousHandle = $(this.handle[handle] || handle);
1423
+
1424
+
1425
+
1426
+ if(value.x !== undefined && value.y !== undefined) {
1427
+ var x = value.x;
1428
+ var y = value.y;
1429
+ } else {
1430
+ var x = value, y = value;
1431
+ }
1432
+
1433
+ if(x && x.constructor != Number) {
1434
+ if (/^\-\=/.test(x) ) {
1435
+ x = this.value(null,1) - parseInt(x.replace('-=', ''), 10);
1436
+ } else if (/^\+\=/.test(x) ) {
1437
+ x = this.value(null,1) + parseInt(x.replace('+=', ''), 10);
1438
+ }
1439
+ }
1440
+
1441
+ if(y && y.constructor != Number) {
1442
+ if (/^\-\=/.test(y) ) {
1443
+ y = this.value(null,2) - parseInt(y.replace('-=', ''), 10);
1444
+ } else if (/^\+\=/.test(y) ) {
1445
+ y = this.value(null,2) + parseInt(y.replace('+=', ''), 10);
1446
+ }
1447
+ }
1448
+
1449
+ if(o.axis != "vertical" && x) {
1450
+ if(o.stepping.x) x = Math.round(x / o.stepping.x) * o.stepping.x;
1451
+ x = this.translateValue(x, 1);
1452
+ x = this.translateLimits(x, 1);
1453
+ x = this.translateRange(x, 1);
1454
+ this.currentHandle.css({ left: x });
1455
+ }
1456
+
1457
+ if(o.axis != "horizontal" && y) {
1458
+ if(o.stepping.y) y = Math.round(y / o.stepping.y) * o.stepping.y;
1459
+ y = this.translateValue(y, 2);
1460
+ y = this.translateLimits(y, 2);
1461
+ y = this.translateRange(y, 2);
1462
+ this.currentHandle.css({ top: y });
1463
+ }
1464
+
1465
+ if (this.rangeElement)
1466
+ this.updateRange();
1467
+
1468
+ if (!noPropagation) {
1469
+ this.propagate('start', null);
1470
+ this.propagate('stop', null);
1471
+ this.propagate('change', null);
1472
+ this.propagate("slide", null);
1473
+ }
1474
+ }
1475
+ });
1476
+
1477
+ $.ui.slider.defaults = {
1478
+ handle: ".ui-slider-handle"
1479
+ };
1480
+
1481
+ })(jQuery);
1482
+
1483
+ /*
1484
+ * jQuery UI Sortable
1485
+ *
1486
+ * Copyright (c) 2008 Paul Bakaus
1487
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
1488
+ * and GPL (GPL-LICENSE.txt) licenses.
1489
+ *
1490
+ * http://docs.jquery.com/UI/Sortables
1491
+ *
1492
+ * Depends:
1493
+ * ui.base.js
1494
+ *
1495
+ * Revision: $Id: ui.sortable.js 5199 2008-04-04 14:04:32Z paul.bakaus $
1496
+ */
1497
+ ;(function($) {
1498
+
1499
+ if (window.Node && Node.prototype && !Node.prototype.contains) {
1500
+ Node.prototype.contains = function (arg) {
1501
+ return !!(this.compareDocumentPosition(arg) & 16);
1502
+ };
1503
+ }
1504
+
1505
+ $.fn.extend({
1506
+ sortable: function(options) {
1507
+
1508
+ var args = Array.prototype.slice.call(arguments, 1);
1509
+
1510
+ if (options == "serialize" || options == "toArray")
1511
+ return $.data(this[0], "sortable")[options](arguments[1]);
1512
+
1513
+ return this.each(function() {
1514
+ if (typeof options == "string") {
1515
+ var sort = $.data(this, "sortable");
1516
+ if (sort) sort[options].apply(sort, args);
1517
+
1518
+ } else if(!$.data(this, "sortable"))
1519
+ new $.ui.sortable(this, options);
1520
+ });
1521
+ }
1522
+ });
1523
+
1524
+ $.ui.sortable = function(element, options) {
1525
+ //Initialize needed constants
1526
+ var self = this;
1527
+
1528
+ this.element = $(element);
1529
+ this.containerCache = {};
1530
+
1531
+ $.data(element, "sortable", this);
1532
+ this.element.addClass("ui-sortable");
1533
+
1534
+ //Prepare the passed options
1535
+ this.options = $.extend({}, options);
1536
+ var o = this.options;
1537
+ $.extend(o, {
1538
+ items: this.options.items || '> *',
1539
+ zIndex: this.options.zIndex || 1000,
1540
+ startCondition: function() {
1541
+ return !self.options.disabled;
1542
+ }
1543
+ });
1544
+
1545
+ $(element).bind("setData.sortable", function(event, key, value){
1546
+ self.options[key] = value;
1547
+ }).bind("getData.sortable", function(event, key){
1548
+ return self.options[key];
1549
+ });
1550
+
1551
+ //Get the items
1552
+ this.refresh();
1553
+
1554
+ //Let's determine if the items are floating
1555
+ this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
1556
+
1557
+ //Let's determine the parent's offset
1558
+ if(!(/(relative|absolute|fixed)/).test(this.element.css('position'))) this.element.css('position', 'relative');
1559
+ this.offset = this.element.offset();
1560
+
1561
+ //Initialize mouse events for interaction
1562
+ this.element.mouseInteraction({
1563
+ executor: this,
1564
+ delay: o.delay,
1565
+ distance: o.distance || 0,
1566
+ dragPrevention: o.prevention ? o.prevention.toLowerCase().split(',') : ['input','textarea','button','select','option'],
1567
+ start: this.start,
1568
+ stop: this.stop,
1569
+ drag: this.drag,
1570
+ condition: function(e) {
1571
+
1572
+ if(this.options.disabled || this.options.type == 'static') return false;
1573
+
1574
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
1575
+ var currentItem = null, nodes = $(e.target).parents().each(function() {
1576
+ if($.data(this, 'sortable-item')) {
1577
+ currentItem = $(this);
1578
+ return false;
1579
+ }
1580
+ });
1581
+ if($.data(e.target, 'sortable-item')) currentItem = $(e.target);
1582
+
1583
+ if(!currentItem) return false;
1584
+ if(this.options.handle) {
1585
+ var validHandle = false;
1586
+ $(this.options.handle, currentItem).each(function() { if(this == e.target) validHandle = true; });
1587
+ if(!validHandle) return false;
1588
+ }
1589
+
1590
+ this.currentItem = currentItem;
1591
+ return true;
1592
+
1593
+ }
1594
+ });
1595
+
1596
+ //Prepare cursorAt
1597
+ if(o.cursorAt && o.cursorAt.constructor == Array)
1598
+ o.cursorAt = { left: o.cursorAt[0], top: o.cursorAt[1] };
1599
+ };
1600
+
1601
+ $.extend($.ui.sortable.prototype, {
1602
+ plugins: {},
1603
+ ui: function(inst) {
1604
+ return {
1605
+ helper: (inst || this)["helper"],
1606
+ placeholder: (inst || this)["placeholder"] || $([]),
1607
+ position: (inst || this)["position"].current,
1608
+ absolutePosition: (inst || this)["position"].absolute,
1609
+ instance: this,
1610
+ options: this.options,
1611
+ element: this.element,
1612
+ item: (inst || this)["currentItem"],
1613
+ sender: inst ? inst.element : null
1614
+ };
1615
+ },
1616
+ propagate: function(n,e,inst) {
1617
+ $.ui.plugin.call(this, n, [e, this.ui(inst)]);
1618
+ this.element.triggerHandler(n == "sort" ? n : "sort"+n, [e, this.ui(inst)], this.options[n]);
1619
+ },
1620
+ serialize: function(o) {
1621
+
1622
+ var items = $(this.options.items, this.element).not('.ui-sortable-helper'); //Only the items of the sortable itself
1623
+ var str = []; o = o || {};
1624
+
1625
+ items.each(function() {
1626
+ var res = ($(this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
1627
+ if(res) str.push((o.key || res[1])+'[]='+(o.key ? res[1] : res[2]));
1628
+ });
1629
+
1630
+ return str.join('&');
1631
+
1632
+ },
1633
+ toArray: function(attr) {
1634
+ var items = $(this.options.items, this.element).not('.ui-sortable-helper'); //Only the items of the sortable itself
1635
+ var ret = [];
1636
+
1637
+ items.each(function() { ret.push($(this).attr(attr || 'id')); });
1638
+ return ret;
1639
+ },
1640
+ enable: function() {
1641
+ this.element.removeClass("ui-sortable-disabled");
1642
+ this.options.disabled = false;
1643
+ },
1644
+ disable: function() {
1645
+ this.element.addClass("ui-sortable-disabled");
1646
+ this.options.disabled = true;
1647
+ },
1648
+ /* Be careful with the following core functions */
1649
+ intersectsWith: function(item) {
1650
+
1651
+ var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,
1652
+ y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;
1653
+ var l = item.left, r = l + item.width,
1654
+ t = item.top, b = t + item.height;
1655
+
1656
+ return ( l < x1 + (this.helperProportions.width / 2) // Right Half
1657
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
1658
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
1659
+ && y2 - (this.helperProportions.height / 2) < b ); // Top Half
1660
+
1661
+ },
1662
+ intersectsWithEdge: function(item) {
1663
+ var x1 = this.position.absolute.left, x2 = x1 + this.helperProportions.width,
1664
+ y1 = this.position.absolute.top, y2 = y1 + this.helperProportions.height;
1665
+ var l = item.left, r = l + item.width,
1666
+ t = item.top, b = t + item.height;
1667
+
1668
+
1669
+ if (!( l < x1 + (this.helperProportions.width / 2) // Right Half
1670
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
1671
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
1672
+ && y2 - (this.helperProportions.height / 2) < b )) return false; // Top Half
1673
+
1674
+ if(this.floating) {
1675
+ if(x2 > l && x1 < l) return 2; //Crosses left edge
1676
+ if(x1 < r && x2 > r) return 1; //Crosses right edge
1677
+ } else {
1678
+ if(y2 > t && y1 < t) return 1; //Crosses top edge
1679
+ if(y1 < b && y2 > b) return 2; //Crosses bottom edge
1680
+ }
1681
+
1682
+ return false;
1683
+
1684
+ },
1685
+ //This method checks approximately if the item is dragged in a container, but doesn't touch any items
1686
+ inEmptyZone: function(container) {
1687
+
1688
+ if(!$(container.options.items, container.element).length) {
1689
+ return container.options.dropOnEmpty ? true : false;
1690
+ };
1691
+
1692
+ var last = $(container.options.items, container.element).not('.ui-sortable-helper'); last = $(last[last.length-1]);
1693
+ var top = last.offset()[this.floating ? 'left' : 'top'] + last[0][this.floating ? 'offsetWidth' : 'offsetHeight'];
1694
+ return (this.position.absolute[this.floating ? 'left' : 'top'] > top);
1695
+ },
1696
+ refresh: function() {
1697
+ this.refreshItems();
1698
+ this.refreshPositions();
1699
+ },
1700
+ refreshItems: function() {
1701
+
1702
+ this.items = [];
1703
+ this.containers = [this];
1704
+ var items = this.items;
1705
+ var queries = [$(this.options.items, this.element)];
1706
+
1707
+ if(this.options.connectWith) {
1708
+ for (var i = this.options.connectWith.length - 1; i >= 0; i--){
1709
+ var cur = $(this.options.connectWith[i]);
1710
+ for (var j = cur.length - 1; j >= 0; j--){
1711
+ var inst = $.data(cur[j], 'sortable');
1712
+ if(inst && !inst.options.disabled) {
1713
+ queries.push($(inst.options.items, inst.element));
1714
+ this.containers.push(inst);
1715
+ }
1716
+ };
1717
+ };
1718
+ }
1719
+
1720
+ for (var i = queries.length - 1; i >= 0; i--){
1721
+ queries[i].each(function() {
1722
+ $.data(this, 'sortable-item', true); // Data for target checking (mouse manager)
1723
+ items.push({
1724
+ item: $(this),
1725
+ width: 0, height: 0,
1726
+ left: 0, top: 0
1727
+ });
1728
+ });
1729
+ };
1730
+
1731
+ },
1732
+ refreshPositions: function(fast) {
1733
+ for (var i = this.items.length - 1; i >= 0; i--){
1734
+ if(!fast) this.items[i].width = this.items[i].item.outerWidth();
1735
+ if(!fast) this.items[i].height = this.items[i].item.outerHeight();
1736
+ var p = this.items[i].item.offset();
1737
+ this.items[i].left = p.left;
1738
+ this.items[i].top = p.top;
1739
+ };
1740
+ for (var i = this.containers.length - 1; i >= 0; i--){
1741
+ var p =this.containers[i].element.offset();
1742
+ this.containers[i].containerCache.left = p.left;
1743
+ this.containers[i].containerCache.top = p.top;
1744
+ this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
1745
+ this.containers[i].containerCache.height= this.containers[i].element.outerHeight();
1746
+ };
1747
+ },
1748
+ destroy: function() {
1749
+ this.element
1750
+ .removeClass("ui-sortable ui-sortable-disabled")
1751
+ .removeData("sortable")
1752
+ .unbind(".sortable")
1753
+ .removeMouseInteraction();
1754
+
1755
+ for ( var i = this.items.length - 1; i >= 0; i-- )
1756
+ this.items[i].item.removeData("sortable-item");
1757
+ },
1758
+ createPlaceholder: function(that) {
1759
+ (that || this).placeholderElement = this.options.placeholderElement ? $(this.options.placeholderElement, (that || this).currentItem) : (that || this).currentItem;
1760
+ (that || this).placeholder = $('<div></div>')
1761
+ .addClass(this.options.placeholder)
1762
+ .appendTo('body')
1763
+ .css({ position: 'absolute' })
1764
+ .css((that || this).placeholderElement.offset())
1765
+ .css({ width: (that || this).placeholderElement.outerWidth(), height: (that || this).placeholderElement.outerHeight() })
1766
+ ;
1767
+ },
1768
+ contactContainers: function(e) {
1769
+ for (var i = this.containers.length - 1; i >= 0; i--){
1770
+
1771
+ if(this.intersectsWith(this.containers[i].containerCache)) {
1772
+ if(!this.containers[i].containerCache.over) {
1773
+
1774
+
1775
+ if(this.currentContainer != this.containers[i]) {
1776
+
1777
+ //When entering a new container, we will find the item with the least distance and append our item near it
1778
+ var dist = 10000; var itemWithLeastDistance = null; var base = this.position.absolute[this.containers[i].floating ? 'left' : 'top'];
1779
+ for (var j = this.items.length - 1; j >= 0; j--) {
1780
+ if(!this.containers[i].element[0].contains(this.items[j].item[0])) continue;
1781
+ var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
1782
+ if(Math.abs(cur - base) < dist) {
1783
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
1784
+ }
1785
+ }
1786
+
1787
+ //We also need to exchange the placeholder
1788
+ if(this.placeholder) this.placeholder.remove();
1789
+ if(this.containers[i].options.placeholder) {
1790
+ this.containers[i].createPlaceholder(this);
1791
+ } else {
1792
+ this.placeholder = null; this.placeholderElement = null;
1793
+ }
1794
+
1795
+
1796
+ itemWithLeastDistance ? this.rearrange(e, itemWithLeastDistance) : this.rearrange(e, null, this.containers[i].element);
1797
+ this.propagate("change", e); //Call plugins and callbacks
1798
+ this.containers[i].propagate("change", e, this); //Call plugins and callbacks
1799
+ this.currentContainer = this.containers[i];
1800
+
1801
+ }
1802
+
1803
+ this.containers[i].propagate("over", e, this);
1804
+ this.containers[i].containerCache.over = 1;
1805
+ }
1806
+ } else {
1807
+ if(this.containers[i].containerCache.over) {
1808
+ this.containers[i].propagate("out", e, this);
1809
+ this.containers[i].containerCache.over = 0;
1810
+ }
1811
+ }
1812
+
1813
+ };
1814
+ },
1815
+ start: function(e,el) {
1816
+
1817
+ var o = this.options;
1818
+ this.refresh();
1819
+
1820
+ //Create and append the visible helper
1821
+ this.helper = typeof o.helper == 'function' ? $(o.helper.apply(this.element[0], [e, this.currentItem])) : this.currentItem.clone();
1822
+ if(!this.helper.parents('body').length) this.helper.appendTo(o.appendTo || this.currentItem[0].parentNode); //Add the helper to the DOM if that didn't happen already
1823
+ this.helper.css({ position: 'absolute', clear: 'both' }).addClass('ui-sortable-helper'); //Position it absolutely and add a helper class
1824
+
1825
+ //Prepare variables for position generation
1826
+ $.extend(this, {
1827
+ offsetParent: this.helper.offsetParent(),
1828
+ offsets: {
1829
+ absolute: this.currentItem.offset()
1830
+ },
1831
+ mouse: {
1832
+ start: { top: e.pageY, left: e.pageX }
1833
+ },
1834
+ margins: {
1835
+ top: parseInt(this.currentItem.css("marginTop")) || 0,
1836
+ left: parseInt(this.currentItem.css("marginLeft")) || 0
1837
+ }
1838
+ });
1839
+
1840
+ //The relative click offset
1841
+ this.offsets.parent = this.offsetParent.offset();
1842
+ this.clickOffset = { left: e.pageX - this.offsets.absolute.left, top: e.pageY - this.offsets.absolute.top };
1843
+
1844
+ this.originalPosition = {
1845
+ left: this.offsets.absolute.left - this.offsets.parent.left - this.margins.left,
1846
+ top: this.offsets.absolute.top - this.offsets.parent.top - this.margins.top
1847
+ }
1848
+
1849
+ //Generate a flexible offset that will later be subtracted from e.pageX/Y
1850
+ //I hate margins - they need to be removed before positioning the element absolutely..
1851
+ this.offset = {
1852
+ left: e.pageX - this.originalPosition.left,
1853
+ top: e.pageY - this.originalPosition.top
1854
+ };
1855
+
1856
+ //Save the first time position
1857
+ $.extend(this, {
1858
+ position: {
1859
+ current: { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left },
1860
+ absolute: { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top },
1861
+ dom: this.currentItem.prev()[0]
1862
+ }
1863
+ });
1864
+
1865
+ //If o.placeholder is used, create a new element at the given position with the class
1866
+ if(o.placeholder) this.createPlaceholder();
1867
+
1868
+ this.propagate("start", e); //Call plugins and callbacks
1869
+ this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; //Save and store the helper proportions
1870
+
1871
+ //If we have something in cursorAt, we'll use it
1872
+ if(o.cursorAt) {
1873
+ if(o.cursorAt.top != undefined || o.cursorAt.bottom != undefined) {
1874
+ this.offset.top -= this.clickOffset.top - (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
1875
+ this.clickOffset.top = (o.cursorAt.top != undefined ? o.cursorAt.top : (this.helperProportions.height - o.cursorAt.bottom));
1876
+ }
1877
+ if(o.cursorAt.left != undefined || o.cursorAt.right != undefined) {
1878
+ this.offset.left -= this.clickOffset.left - (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
1879
+ this.clickOffset.left = (o.cursorAt.left != undefined ? o.cursorAt.left : (this.helperProportions.width - o.cursorAt.right));
1880
+ }
1881
+ }
1882
+
1883
+ if(this.options.placeholder != 'clone') $(this.currentItem).css('visibility', 'hidden'); //Set the original element visibility to hidden to still fill out the white space
1884
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i].propagate("activate", e, this); } //Post 'activate' events to possible containers
1885
+
1886
+ //Prepare possible droppables
1887
+ if($.ui.ddmanager) $.ui.ddmanager.current = this;
1888
+ if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, e);
1889
+
1890
+ this.dragging = true;
1891
+ return false;
1892
+
1893
+ },
1894
+ stop: function(e) {
1895
+
1896
+ this.propagate("stop", e); //Call plugins and trigger callbacks
1897
+ if(this.position.dom != this.currentItem.prev()[0]) this.propagate("update", e); //Trigger update callback if the DOM position has changed
1898
+ if(!this.element[0].contains(this.currentItem[0])) { //Node was moved out of the current element
1899
+ this.propagate("remove", e);
1900
+ for (var i = this.containers.length - 1; i >= 0; i--){
1901
+ if(this.containers[i].element[0].contains(this.currentItem[0])) {
1902
+ this.containers[i].propagate("update", e, this);
1903
+ this.containers[i].propagate("receive", e, this);
1904
+ }
1905
+ };
1906
+ };
1907
+
1908
+ //Post events to containers
1909
+ for (var i = this.containers.length - 1; i >= 0; i--){
1910
+ this.containers[i].propagate("deactivate", e, this);
1911
+ if(this.containers[i].containerCache.over) {
1912
+ this.containers[i].propagate("out", e, this);
1913
+ this.containers[i].containerCache.over = 0;
1914
+ }
1915
+ }
1916
+
1917
+ //If we are using droppables, inform the manager about the drop
1918
+ if ($.ui.ddmanager && !this.options.dropBehaviour) $.ui.ddmanager.drop(this, e);
1919
+
1920
+ this.dragging = false;
1921
+ if(this.cancelHelperRemoval) return false;
1922
+ $(this.currentItem).css('visibility', '');
1923
+ if(this.placeholder) this.placeholder.remove();
1924
+ this.helper.remove();
1925
+
1926
+ return false;
1927
+
1928
+ },
1929
+ drag: function(e) {
1930
+
1931
+ //Compute the helpers position
1932
+ this.position.current = { top: e.pageY - this.offset.top, left: e.pageX - this.offset.left };
1933
+ this.position.absolute = { left: e.pageX - this.clickOffset.left, top: e.pageY - this.clickOffset.top };
1934
+
1935
+ //Rearrange
1936
+ for (var i = this.items.length - 1; i >= 0; i--) {
1937
+ var intersection = this.intersectsWithEdge(this.items[i]);
1938
+ if(!intersection) continue;
1939
+
1940
+ if( this.items[i].item[0] != this.currentItem[0] //cannot intersect with itself
1941
+ && this.currentItem[intersection == 1 ? "next" : "prev"]()[0] != this.items[i].item[0] //no useless actions that have been done before
1942
+ && !this.currentItem[0].contains(this.items[i].item[0]) //no action if the item moved is the parent of the item checked
1943
+ && (this.options.type == 'semi-dynamic' ? !this.element[0].contains(this.items[i].item[0]) : true)
1944
+ ) {
1945
+
1946
+ this.direction = intersection == 1 ? "down" : "up";
1947
+ this.rearrange(e, this.items[i]);
1948
+ this.propagate("change", e); //Call plugins and callbacks
1949
+ break;
1950
+ }
1951
+ }
1952
+
1953
+ //Post events to containers
1954
+ this.contactContainers(e);
1955
+
1956
+ //Interconnect with droppables
1957
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, e);
1958
+
1959
+ this.propagate("sort", e); //Call plugins and callbacks
1960
+ this.helper.css({ left: this.position.current.left+'px', top: this.position.current.top+'px' }); // Stick the helper to the cursor
1961
+ return false;
1962
+
1963
+ },
1964
+ rearrange: function(e, i, a) {
1965
+ a ? a.append(this.currentItem) : i.item[this.direction == 'down' ? 'before' : 'after'](this.currentItem);
1966
+ this.refreshPositions(true); //Precompute after each DOM insertion, NOT on mousemove
1967
+ if(this.placeholderElement) this.placeholder.css(this.placeholderElement.offset());
1968
+ }
1969
+ });
1970
+
1971
+ /*
1972
+ * Sortable Extensions
1973
+ */
1974
+
1975
+ $.ui.plugin.add("sortable", "cursor", {
1976
+ start: function(e, ui) {
1977
+ var t = $('body');
1978
+ if (t.css("cursor")) ui.options._cursor = t.css("cursor");
1979
+ t.css("cursor", ui.options.cursor);
1980
+ },
1981
+ stop: function(e, ui) {
1982
+ if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
1983
+ }
1984
+ });
1985
+
1986
+ $.ui.plugin.add("sortable", "zIndex", {
1987
+ start: function(e, ui) {
1988
+ var t = ui.helper;
1989
+ if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
1990
+ t.css('zIndex', ui.options.zIndex);
1991
+ },
1992
+ stop: function(e, ui) {
1993
+ if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
1994
+ }
1995
+ });
1996
+
1997
+ $.ui.plugin.add("sortable", "opacity", {
1998
+ start: function(e, ui) {
1999
+ var t = ui.helper;
2000
+ if(t.css("opacity")) ui.options._opacity = t.css("opacity");
2001
+ t.css('opacity', ui.options.opacity);
2002
+ },
2003
+ stop: function(e, ui) {
2004
+ if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
2005
+ }
2006
+ });
2007
+
2008
+
2009
+ $.ui.plugin.add("sortable", "revert", {
2010
+ stop: function(e, ui) {
2011
+ var self = ui.instance;
2012
+ self.cancelHelperRemoval = true;
2013
+ var cur = self.currentItem.offset();
2014
+ var op = self.helper.offsetParent().offset();
2015
+ if(ui.instance.options.zIndex) ui.helper.css('zIndex', ui.instance.options.zIndex); //Do the zIndex again because it already was resetted by the plugin above on stop
2016
+
2017
+ //Also animate the placeholder if we have one
2018
+ if(ui.instance.placeholder) ui.instance.placeholder.animate({ opacity: 'hide' }, parseInt(ui.options.revert, 10) || 500);
2019
+
2020
+
2021
+ ui.helper.animate({
2022
+ left: cur.left - op.left - self.margins.left,
2023
+ top: cur.top - op.top - self.margins.top
2024
+ }, parseInt(ui.options.revert, 10) || 500, function() {
2025
+ self.currentItem.css('visibility', 'visible');
2026
+ window.setTimeout(function() {
2027
+ if(self.placeholder) self.placeholder.remove();
2028
+ self.helper.remove();
2029
+ if(ui.options._zIndex) ui.helper.css('zIndex', ui.options._zIndex);
2030
+ }, 50);
2031
+ });
2032
+ }
2033
+ });
2034
+
2035
+
2036
+ $.ui.plugin.add("sortable", "containment", {
2037
+ start: function(e, ui) {
2038
+
2039
+ var o = ui.options;
2040
+ if((o.containment.left != undefined || o.containment.constructor == Array) && !o._containment) return;
2041
+ if(!o._containment) o._containment = o.containment;
2042
+
2043
+ if(o._containment == 'parent') o._containment = this[0].parentNode;
2044
+ if(o._containment == 'sortable') o._containment = this[0];
2045
+ if(o._containment == 'document') {
2046
+ o.containment = [
2047
+ 0,
2048
+ 0,
2049
+ $(document).width(),
2050
+ ($(document).height() || document.body.parentNode.scrollHeight)
2051
+ ];
2052
+ } else { //I'm a node, so compute top/left/right/bottom
2053
+
2054
+ var ce = $(o._containment);
2055
+ var co = ce.offset();
2056
+
2057
+ o.containment = [
2058
+ co.left,
2059
+ co.top,
2060
+ co.left+(ce.outerWidth() || ce[0].scrollWidth),
2061
+ co.top+(ce.outerHeight() || ce[0].scrollHeight)
2062
+ ];
2063
+ }
2064
+
2065
+ },
2066
+ sort: function(e, ui) {
2067
+
2068
+ var o = ui.options;
2069
+ var h = ui.helper;
2070
+ var c = o.containment;
2071
+ var self = ui.instance;
2072
+ var borderLeft = (parseInt(self.offsetParent.css("borderLeftWidth"), 10) || 0);
2073
+ var borderRight = (parseInt(self.offsetParent.css("borderRightWidth"), 10) || 0);
2074
+ var borderTop = (parseInt(self.offsetParent.css("borderTopWidth"), 10) || 0);
2075
+ var borderBottom = (parseInt(self.offsetParent.css("borderBottomWidth"), 10) || 0);
2076
+
2077
+ if(c.constructor == Array) {
2078
+ if((self.position.absolute.left < c[0])) self.position.current.left = c[0] - self.offsets.parent.left - self.margins.left;
2079
+ if((self.position.absolute.top < c[1])) self.position.current.top = c[1] - self.offsets.parent.top - self.margins.top;
2080
+ if(self.position.absolute.left - c[2] + self.helperProportions.width >= 0) self.position.current.left = c[2] - self.offsets.parent.left - self.helperProportions.width - self.margins.left - borderLeft - borderRight;
2081
+ if(self.position.absolute.top - c[3] + self.helperProportions.height >= 0) self.position.current.top = c[3] - self.offsets.parent.top - self.helperProportions.height - self.margins.top - borderTop - borderBottom;
2082
+ } else {
2083
+ if((ui.position.left < c.left)) self.position.current.left = c.left;
2084
+ if((ui.position.top < c.top)) self.position.current.top = c.top;
2085
+ if(ui.position.left - self.offsetParent.innerWidth() + self.helperProportions.width + c.right + borderLeft + borderRight >= 0) self.position.current.left = self.offsetParent.innerWidth() - self.helperProportions.width - c.right - borderLeft - borderRight;
2086
+ if(ui.position.top - self.offsetParent.innerHeight() + self.helperProportions.height + c.bottom + borderTop + borderBottom >= 0) self.position.current.top = self.offsetParent.innerHeight() - self.helperProportions.height - c.bottom - borderTop - borderBottom;
2087
+ }
2088
+
2089
+ }
2090
+ });
2091
+
2092
+ $.ui.plugin.add("sortable", "axis", {
2093
+ sort: function(e, ui) {
2094
+ var o = ui.options;
2095
+ if(o.constraint) o.axis = o.constraint; //Legacy check
2096
+ o.axis == 'x' ? ui.instance.position.top = ui.instance.originalPosition.top : ui.instance.position.left = ui.instance.originalPosition.left;
2097
+ }
2098
+ });
2099
+
2100
+ $.ui.plugin.add("sortable", "scroll", {
2101
+ start: function(e, ui) {
2102
+ var o = ui.options;
2103
+ o.scrollSensitivity = o.scrollSensitivity || 20;
2104
+ o.scrollSpeed = o.scrollSpeed || 20;
2105
+
2106
+ ui.instance.overflowY = function(el) {
2107
+ do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-y'))) return el; el = el.parent(); } while (el[0].parentNode);
2108
+ return $(document);
2109
+ }(this);
2110
+ ui.instance.overflowX = function(el) {
2111
+ do { if((/auto|scroll/).test(el.css('overflow')) || (/auto|scroll/).test(el.css('overflow-x'))) return el; el = el.parent(); } while (el[0].parentNode);
2112
+ return $(document);
2113
+ }(this);
2114
+
2115
+ if(ui.instance.overflowY[0] != document && ui.instance.overflowY[0].tagName != 'HTML') ui.instance.overflowYstart = ui.instance.overflowY[0].scrollTop;
2116
+ if(ui.instance.overflowX[0] != document && ui.instance.overflowX[0].tagName != 'HTML') ui.instance.overflowXstart = ui.instance.overflowX[0].scrollLeft;
2117
+
2118
+ },
2119
+ sort: function(e, ui) {
2120
+
2121
+ var o = ui.options;
2122
+ var i = ui.instance;
2123
+
2124
+ if(i.overflowY[0] != document && i.overflowY[0].tagName != 'HTML') {
2125
+ if(i.overflowY[0].offsetHeight - (ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
2126
+ i.overflowY[0].scrollTop = i.overflowY[0].scrollTop + o.scrollSpeed;
2127
+ if((ui.position.top - i.overflowY[0].scrollTop + i.clickOffset.top) < o.scrollSensitivity)
2128
+ i.overflowY[0].scrollTop = i.overflowY[0].scrollTop - o.scrollSpeed;
2129
+ } else {
2130
+ //$(document.body).append('<p>'+(e.pageY - $(document).scrollTop())+'</p>');
2131
+ if(e.pageY - $(document).scrollTop() < o.scrollSensitivity)
2132
+ $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2133
+ if($(window).height() - (e.pageY - $(document).scrollTop()) < o.scrollSensitivity)
2134
+ $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2135
+ }
2136
+
2137
+ if(i.overflowX[0] != document && i.overflowX[0].tagName != 'HTML') {
2138
+ if(i.overflowX[0].offsetWidth - (ui.position.left - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
2139
+ i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft + o.scrollSpeed;
2140
+ if((ui.position.top - i.overflowX[0].scrollLeft + i.clickOffset.left) < o.scrollSensitivity)
2141
+ i.overflowX[0].scrollLeft = i.overflowX[0].scrollLeft - o.scrollSpeed;
2142
+ } else {
2143
+ if(e.pageX - $(document).scrollLeft() < o.scrollSensitivity)
2144
+ $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2145
+ if($(window).width() - (e.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
2146
+ $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2147
+ }
2148
+
2149
+ //ui.instance.recallOffset(e);
2150
+ i.offset = {
2151
+ left: i.mouse.start.left - i.originalPosition.left + (i.overflowXstart !== undefined ? i.overflowXstart - i.overflowX[0].scrollLeft : 0),
2152
+ top: i.mouse.start.top - i.originalPosition.top + (i.overflowYstart !== undefined ? i.overflowYstart - i.overflowX[0].scrollTop : 0)
2153
+ };
2154
+
2155
+ }
2156
+ });
2157
+
2158
+ })(jQuery);