source: other-projects/tipple-android/i-greenstone-server-files/greenstone/webapps/greenstone3/interfaces/default/js/jquery-ui-1.8.15/ui/jquery.ui.draggable.js@ 26899

Last change on this file since 26899 was 26899, checked in by davidb, 11 years ago

Tipple reborn after Chris's Summer of Code 2013

File size: 30.2 KB
Line 
1/*
2 * jQuery UI Draggable 1.8.15
3 *
4 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5 * Dual licensed under the MIT or GPL Version 2 licenses.
6 * http://jquery.org/license
7 *
8 * http://docs.jquery.com/UI/Draggables
9 *
10 * Depends:
11 * jquery.ui.core.js
12 * jquery.ui.mouse.js
13 * jquery.ui.widget.js
14 */
15(function( $, undefined ) {
16
17$.widget("ui.draggable", $.ui.mouse, {
18 widgetEventPrefix: "drag",
19 options: {
20 addClasses: true,
21 appendTo: "parent",
22 axis: false,
23 connectToSortable: false,
24 containment: false,
25 cursor: "auto",
26 cursorAt: false,
27 grid: false,
28 handle: false,
29 helper: "original",
30 iframeFix: false,
31 opacity: false,
32 refreshPositions: false,
33 revert: false,
34 revertDuration: 500,
35 scope: "default",
36 scroll: true,
37 scrollSensitivity: 20,
38 scrollSpeed: 20,
39 snap: false,
40 snapMode: "both",
41 snapTolerance: 20,
42 stack: false,
43 zIndex: false
44 },
45 _create: function() {
46
47 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
48 this.element[0].style.position = 'relative';
49
50 (this.options.addClasses && this.element.addClass("ui-draggable"));
51 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
52
53 this._mouseInit();
54
55 },
56
57 destroy: function() {
58 if(!this.element.data('draggable')) return;
59 this.element
60 .removeData("draggable")
61 .unbind(".draggable")
62 .removeClass("ui-draggable"
63 + " ui-draggable-dragging"
64 + " ui-draggable-disabled");
65 this._mouseDestroy();
66
67 return this;
68 },
69
70 _mouseCapture: function(event) {
71
72 var o = this.options;
73
74 // among others, prevent a drag on a resizable-handle
75 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
76 return false;
77
78 //Quit if we're not on a valid handle
79 this.handle = this._getHandle(event);
80 if (!this.handle)
81 return false;
82
83 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
84 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
85 .css({
86 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
87 position: "absolute", opacity: "0.001", zIndex: 1000
88 })
89 .css($(this).offset())
90 .appendTo("body");
91 });
92
93 return true;
94
95 },
96
97 _mouseStart: function(event) {
98
99 var o = this.options;
100
101 //Create and append the visible helper
102 this.helper = this._createHelper(event);
103
104 //Cache the helper size
105 this._cacheHelperProportions();
106
107 //If ddmanager is used for droppables, set the global draggable
108 if($.ui.ddmanager)
109 $.ui.ddmanager.current = this;
110
111 /*
112 * - Position generation -
113 * This block generates everything position related - it's the core of draggables.
114 */
115
116 //Cache the margins of the original element
117 this._cacheMargins();
118
119 //Store the helper's css position
120 this.cssPosition = this.helper.css("position");
121 this.scrollParent = this.helper.scrollParent();
122
123 //The element's absolute position on the page minus margins
124 this.offset = this.positionAbs = this.element.offset();
125 this.offset = {
126 top: this.offset.top - this.margins.top,
127 left: this.offset.left - this.margins.left
128 };
129
130 $.extend(this.offset, {
131 click: { //Where the click happened, relative to the element
132 left: event.pageX - this.offset.left,
133 top: event.pageY - this.offset.top
134 },
135 parent: this._getParentOffset(),
136 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
137 });
138
139 //Generate the original position
140 this.originalPosition = this.position = this._generatePosition(event);
141 this.originalPageX = event.pageX;
142 this.originalPageY = event.pageY;
143
144 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
145 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
146
147 //Set a containment if given in the options
148 if(o.containment)
149 this._setContainment();
150
151 //Trigger event + callbacks
152 if(this._trigger("start", event) === false) {
153 this._clear();
154 return false;
155 }
156
157 //Recache the helper size
158 this._cacheHelperProportions();
159
160 //Prepare the droppable offsets
161 if ($.ui.ddmanager && !o.dropBehaviour)
162 $.ui.ddmanager.prepareOffsets(this, event);
163
164 this.helper.addClass("ui-draggable-dragging");
165 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
166
167 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
168 if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
169
170 return true;
171 },
172
173 _mouseDrag: function(event, noPropagation) {
174
175 //Compute the helpers position
176 this.position = this._generatePosition(event);
177 this.positionAbs = this._convertPositionTo("absolute");
178
179 //Call plugins and callbacks and use the resulting position if something is returned
180 if (!noPropagation) {
181 var ui = this._uiHash();
182 if(this._trigger('drag', event, ui) === false) {
183 this._mouseUp({});
184 return false;
185 }
186 this.position = ui.position;
187 }
188
189 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
190 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
191 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
192
193 return false;
194 },
195
196 _mouseStop: function(event) {
197
198 //If we are using droppables, inform the manager about the drop
199 var dropped = false;
200 if ($.ui.ddmanager && !this.options.dropBehaviour)
201 dropped = $.ui.ddmanager.drop(this, event);
202
203 //if a drop comes from outside (a sortable)
204 if(this.dropped) {
205 dropped = this.dropped;
206 this.dropped = false;
207 }
208
209 //if the original element is removed, don't bother to continue if helper is set to "original"
210 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
211 return false;
212
213 if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
214 var self = this;
215 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
216 if(self._trigger("stop", event) !== false) {
217 self._clear();
218 }
219 });
220 } else {
221 if(this._trigger("stop", event) !== false) {
222 this._clear();
223 }
224 }
225
226 return false;
227 },
228
229 _mouseUp: function(event) {
230 if (this.options.iframeFix === true) {
231 $("div.ui-draggable-iframeFix").each(function() {
232 this.parentNode.removeChild(this);
233 }); //Remove frame helpers
234 }
235
236 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
237 if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
238
239 return $.ui.mouse.prototype._mouseUp.call(this, event);
240 },
241
242 cancel: function() {
243
244 if(this.helper.is(".ui-draggable-dragging")) {
245 this._mouseUp({});
246 } else {
247 this._clear();
248 }
249
250 return this;
251
252 },
253
254 _getHandle: function(event) {
255
256 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
257 $(this.options.handle, this.element)
258 .find("*")
259 .andSelf()
260 .each(function() {
261 if(this == event.target) handle = true;
262 });
263
264 return handle;
265
266 },
267
268 _createHelper: function(event) {
269
270 var o = this.options;
271 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
272
273 if(!helper.parents('body').length)
274 helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
275
276 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
277 helper.css("position", "absolute");
278
279 return helper;
280
281 },
282
283 _adjustOffsetFromHelper: function(obj) {
284 if (typeof obj == 'string') {
285 obj = obj.split(' ');
286 }
287 if ($.isArray(obj)) {
288 obj = {left: +obj[0], top: +obj[1] || 0};
289 }
290 if ('left' in obj) {
291 this.offset.click.left = obj.left + this.margins.left;
292 }
293 if ('right' in obj) {
294 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
295 }
296 if ('top' in obj) {
297 this.offset.click.top = obj.top + this.margins.top;
298 }
299 if ('bottom' in obj) {
300 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
301 }
302 },
303
304 _getParentOffset: function() {
305
306 //Get the offsetParent and cache its position
307 this.offsetParent = this.helper.offsetParent();
308 var po = this.offsetParent.offset();
309
310 // This is a special case where we need to modify a offset calculated on start, since the following happened:
311 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
312 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
313 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
314 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
315 po.left += this.scrollParent.scrollLeft();
316 po.top += this.scrollParent.scrollTop();
317 }
318
319 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
320 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
321 po = { top: 0, left: 0 };
322
323 return {
324 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
325 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
326 };
327
328 },
329
330 _getRelativeOffset: function() {
331
332 if(this.cssPosition == "relative") {
333 var p = this.element.position();
334 return {
335 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
336 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
337 };
338 } else {
339 return { top: 0, left: 0 };
340 }
341
342 },
343
344 _cacheMargins: function() {
345 this.margins = {
346 left: (parseInt(this.element.css("marginLeft"),10) || 0),
347 top: (parseInt(this.element.css("marginTop"),10) || 0),
348 right: (parseInt(this.element.css("marginRight"),10) || 0),
349 bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
350 };
351 },
352
353 _cacheHelperProportions: function() {
354 this.helperProportions = {
355 width: this.helper.outerWidth(),
356 height: this.helper.outerHeight()
357 };
358 },
359
360 _setContainment: function() {
361
362 var o = this.options;
363 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
364 if(o.containment == 'document' || o.containment == 'window') this.containment = [
365 o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
366 o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
367 (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
368 (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
369 ];
370
371 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
372 var c = $(o.containment);
373 var ce = c[0]; if(!ce) return;
374 var co = c.offset();
375 var over = ($(ce).css("overflow") != 'hidden');
376
377 this.containment = [
378 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
379 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
380 (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 - this.margins.right,
381 (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 - this.margins.bottom
382 ];
383 this.relative_container = c;
384
385 } else if(o.containment.constructor == Array) {
386 this.containment = o.containment;
387 }
388
389 },
390
391 _convertPositionTo: function(d, pos) {
392
393 if(!pos) pos = this.position;
394 var mod = d == "absolute" ? 1 : -1;
395 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
396
397 return {
398 top: (
399 pos.top // The absolute mouse position
400 + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
401 + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
402 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
403 ),
404 left: (
405 pos.left // The absolute mouse position
406 + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
407 + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
408 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
409 )
410 };
411
412 },
413
414 _generatePosition: function(event) {
415
416 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
417 var pageX = event.pageX;
418 var pageY = event.pageY;
419
420 /*
421 * - Position constraining -
422 * Constrain the position to a mix of grid, containment.
423 */
424
425 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
426 var containment;
427 if(this.containment) {
428 if (this.relative_container){
429 var co = this.relative_container.offset();
430 containment = [ this.containment[0] + co.left,
431 this.containment[1] + co.top,
432 this.containment[2] + co.left,
433 this.containment[3] + co.top ];
434 }
435 else {
436 containment = this.containment;
437 }
438
439 if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
440 if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
441 if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
442 if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
443 }
444
445 if(o.grid) {
446 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
447 var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
448 pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
449
450 var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
451 pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
452 }
453
454 }
455
456 return {
457 top: (
458 pageY // The absolute mouse position
459 - this.offset.click.top // Click offset (relative to the element)
460 - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
461 - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
462 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
463 ),
464 left: (
465 pageX // The absolute mouse position
466 - this.offset.click.left // Click offset (relative to the element)
467 - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
468 - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
469 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
470 )
471 };
472
473 },
474
475 _clear: function() {
476 this.helper.removeClass("ui-draggable-dragging");
477 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
478 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
479 this.helper = null;
480 this.cancelHelperRemoval = false;
481 },
482
483 // From now on bulk stuff - mainly helpers
484
485 _trigger: function(type, event, ui) {
486 ui = ui || this._uiHash();
487 $.ui.plugin.call(this, type, [event, ui]);
488 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
489 return $.Widget.prototype._trigger.call(this, type, event, ui);
490 },
491
492 plugins: {},
493
494 _uiHash: function(event) {
495 return {
496 helper: this.helper,
497 position: this.position,
498 originalPosition: this.originalPosition,
499 offset: this.positionAbs
500 };
501 }
502
503});
504
505$.extend($.ui.draggable, {
506 version: "1.8.15"
507});
508
509$.ui.plugin.add("draggable", "connectToSortable", {
510 start: function(event, ui) {
511
512 var inst = $(this).data("draggable"), o = inst.options,
513 uiSortable = $.extend({}, ui, { item: inst.element });
514 inst.sortables = [];
515 $(o.connectToSortable).each(function() {
516 var sortable = $.data(this, 'sortable');
517 if (sortable && !sortable.options.disabled) {
518 inst.sortables.push({
519 instance: sortable,
520 shouldRevert: sortable.options.revert
521 });
522 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
523 sortable._trigger("activate", event, uiSortable);
524 }
525 });
526
527 },
528 stop: function(event, ui) {
529
530 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
531 var inst = $(this).data("draggable"),
532 uiSortable = $.extend({}, ui, { item: inst.element });
533
534 $.each(inst.sortables, function() {
535 if(this.instance.isOver) {
536
537 this.instance.isOver = 0;
538
539 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
540 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
541
542 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
543 if(this.shouldRevert) this.instance.options.revert = true;
544
545 //Trigger the stop of the sortable
546 this.instance._mouseStop(event);
547
548 this.instance.options.helper = this.instance.options._helper;
549
550 //If the helper has been the original item, restore properties in the sortable
551 if(inst.options.helper == 'original')
552 this.instance.currentItem.css({ top: 'auto', left: 'auto' });
553
554 } else {
555 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
556 this.instance._trigger("deactivate", event, uiSortable);
557 }
558
559 });
560
561 },
562 drag: function(event, ui) {
563
564 var inst = $(this).data("draggable"), self = this;
565
566 var checkPos = function(o) {
567 var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
568 var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
569 var itemHeight = o.height, itemWidth = o.width;
570 var itemTop = o.top, itemLeft = o.left;
571
572 return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
573 };
574
575 $.each(inst.sortables, function(i) {
576
577 //Copy over some variables to allow calling the sortable's native _intersectsWith
578 this.instance.positionAbs = inst.positionAbs;
579 this.instance.helperProportions = inst.helperProportions;
580 this.instance.offset.click = inst.offset.click;
581
582 if(this.instance._intersectsWith(this.instance.containerCache)) {
583
584 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
585 if(!this.instance.isOver) {
586
587 this.instance.isOver = 1;
588 //Now we fake the start of dragging for the sortable instance,
589 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
590 //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)
591 this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
592 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
593 this.instance.options.helper = function() { return ui.helper[0]; };
594
595 event.target = this.instance.currentItem[0];
596 this.instance._mouseCapture(event, true);
597 this.instance._mouseStart(event, true, true);
598
599 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
600 this.instance.offset.click.top = inst.offset.click.top;
601 this.instance.offset.click.left = inst.offset.click.left;
602 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
603 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
604
605 inst._trigger("toSortable", event);
606 inst.dropped = this.instance.element; //draggable revert needs that
607 //hack so receive/update callbacks work (mostly)
608 inst.currentItem = inst.element;
609 this.instance.fromOutside = inst;
610
611 }
612
613 //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
614 if(this.instance.currentItem) this.instance._mouseDrag(event);
615
616 } else {
617
618 //If it doesn't intersect with the sortable, and it intersected before,
619 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
620 if(this.instance.isOver) {
621
622 this.instance.isOver = 0;
623 this.instance.cancelHelperRemoval = true;
624
625 //Prevent reverting on this forced stop
626 this.instance.options.revert = false;
627
628 // The out event needs to be triggered independently
629 this.instance._trigger('out', event, this.instance._uiHash(this.instance));
630
631 this.instance._mouseStop(event, true);
632 this.instance.options.helper = this.instance.options._helper;
633
634 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
635 this.instance.currentItem.remove();
636 if(this.instance.placeholder) this.instance.placeholder.remove();
637
638 inst._trigger("fromSortable", event);
639 inst.dropped = false; //draggable revert needs that
640 }
641
642 };
643
644 });
645
646 }
647});
648
649$.ui.plugin.add("draggable", "cursor", {
650 start: function(event, ui) {
651 var t = $('body'), o = $(this).data('draggable').options;
652 if (t.css("cursor")) o._cursor = t.css("cursor");
653 t.css("cursor", o.cursor);
654 },
655 stop: function(event, ui) {
656 var o = $(this).data('draggable').options;
657 if (o._cursor) $('body').css("cursor", o._cursor);
658 }
659});
660
661$.ui.plugin.add("draggable", "opacity", {
662 start: function(event, ui) {
663 var t = $(ui.helper), o = $(this).data('draggable').options;
664 if(t.css("opacity")) o._opacity = t.css("opacity");
665 t.css('opacity', o.opacity);
666 },
667 stop: function(event, ui) {
668 var o = $(this).data('draggable').options;
669 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
670 }
671});
672
673$.ui.plugin.add("draggable", "scroll", {
674 start: function(event, ui) {
675 var i = $(this).data("draggable");
676 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
677 },
678 drag: function(event, ui) {
679
680 var i = $(this).data("draggable"), o = i.options, scrolled = false;
681
682 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
683
684 if(!o.axis || o.axis != 'x') {
685 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
686 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
687 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
688 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
689 }
690
691 if(!o.axis || o.axis != 'y') {
692 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
693 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
694 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
695 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
696 }
697
698 } else {
699
700 if(!o.axis || o.axis != 'x') {
701 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
702 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
703 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
704 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
705 }
706
707 if(!o.axis || o.axis != 'y') {
708 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
709 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
710 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
711 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
712 }
713
714 }
715
716 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
717 $.ui.ddmanager.prepareOffsets(i, event);
718
719 }
720});
721
722$.ui.plugin.add("draggable", "snap", {
723 start: function(event, ui) {
724
725 var i = $(this).data("draggable"), o = i.options;
726 i.snapElements = [];
727
728 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
729 var $t = $(this); var $o = $t.offset();
730 if(this != i.element[0]) i.snapElements.push({
731 item: this,
732 width: $t.outerWidth(), height: $t.outerHeight(),
733 top: $o.top, left: $o.left
734 });
735 });
736
737 },
738 drag: function(event, ui) {
739
740 var inst = $(this).data("draggable"), o = inst.options;
741 var d = o.snapTolerance;
742
743 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
744 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
745
746 for (var i = inst.snapElements.length - 1; i >= 0; i--){
747
748 var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
749 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
750
751 //Yes, I know, this is insane ;)
752 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))) {
753 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
754 inst.snapElements[i].snapping = false;
755 continue;
756 }
757
758 if(o.snapMode != 'inner') {
759 var ts = Math.abs(t - y2) <= d;
760 var bs = Math.abs(b - y1) <= d;
761 var ls = Math.abs(l - x2) <= d;
762 var rs = Math.abs(r - x1) <= d;
763 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
764 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
765 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
766 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
767 }
768
769 var first = (ts || bs || ls || rs);
770
771 if(o.snapMode != 'outer') {
772 var ts = Math.abs(t - y1) <= d;
773 var bs = Math.abs(b - y2) <= d;
774 var ls = Math.abs(l - x1) <= d;
775 var rs = Math.abs(r - x2) <= d;
776 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
777 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
778 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
779 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
780 }
781
782 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
783 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
784 inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
785
786 };
787
788 }
789});
790
791$.ui.plugin.add("draggable", "stack", {
792 start: function(event, ui) {
793
794 var o = $(this).data("draggable").options;
795
796 var group = $.makeArray($(o.stack)).sort(function(a,b) {
797 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
798 });
799 if (!group.length) { return; }
800
801 var min = parseInt(group[0].style.zIndex) || 0;
802 $(group).each(function(i) {
803 this.style.zIndex = min + i;
804 });
805
806 this[0].style.zIndex = min + group.length;
807
808 }
809});
810
811$.ui.plugin.add("draggable", "zIndex", {
812 start: function(event, ui) {
813 var t = $(ui.helper), o = $(this).data("draggable").options;
814 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
815 t.css('zIndex', o.zIndex);
816 },
817 stop: function(event, ui) {
818 var o = $(this).data("draggable").options;
819 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
820 }
821});
822
823})(jQuery);
Note: See TracBrowser for help on using the repository browser.