[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/resources/lib/jquery.ui/ -> jquery.ui.draggable.js (source)

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


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1