source: trunk/themes/default/js/ui/jquery.ui.draggable.js @ 12525

Last change on this file since 12525 was 12525, checked in by patdenice, 12 years ago

feature:2487
Update jQuery to 1.6.4 and jQuery UI to 1.8.16

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