app/assets/javascripts/jquery.ui.draggable.js in jquery-ui-rails-4.0.2 vs app/assets/javascripts/jquery.ui.draggable.js in jquery-ui-rails-4.0.3

- old
+ new

@@ -1,11 +1,11 @@ //= require jquery.ui.core //= require jquery.ui.widget //= require jquery.ui.mouse /*! - * jQuery UI Draggable 1.10.0 + * jQuery UI Draggable 1.10.3 * http://jqueryui.com * * Copyright 2013 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license @@ -18,11 +18,11 @@ * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.draggable", $.ui.mouse, { - version: "1.10.0", + version: "1.10.3", widgetEventPrefix: "drag", options: { addClasses: true, appendTo: "parent", axis: false, @@ -127,20 +127,25 @@ //Cache the margins of the original element this._cacheMargins(); //Store the helper's css position - this.cssPosition = this.helper.css("position"); + this.cssPosition = this.helper.css( "position" ); this.scrollParent = this.helper.scrollParent(); + this.offsetParent = this.helper.offsetParent(); + this.offsetParentCssPosition = this.offsetParent.css( "position" ); //The element's absolute position on the page minus margins this.offset = this.positionAbs = this.element.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; + //Reset scroll cache + this.offset.scroll = false; + $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, @@ -155,13 +160,11 @@ //Adjust the mouse offset relative to the helper if "cursorAt" is supplied (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Set a containment if given in the options - if(o.containment) { - this._setContainment(); - } + this._setContainment(); //Trigger event + callbacks if(this._trigger("start", event) === false) { this._clear(); return false; @@ -185,10 +188,14 @@ return true; }, _mouseDrag: function(event, noPropagation) { + // reset any necessary cached properties (see #5009) + if ( this.offsetParentCssPosition === "fixed" ) { + this.offset.parent = this._getParentOffset(); + } //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); @@ -216,13 +223,11 @@ }, _mouseStop: function(event) { //If we are using droppables, inform the manager about the drop - var element, - that = this, - elementInDom = false, + var that = this, dropped = false; if ($.ui.ddmanager && !this.options.dropBehaviour) { dropped = $.ui.ddmanager.drop(this, event); } @@ -231,17 +236,11 @@ dropped = this.dropped; this.dropped = false; } //if the original element is no longer in the DOM don't bother to continue (see #8269) - element = this.element[0]; - while ( element && (element = element.parentNode) ) { - if (element === document ) { - elementInDom = true; - } - } - if ( !elementInDom && this.options.helper === "original" ) { + if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { return false; } 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))) { $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { @@ -283,23 +282,13 @@ return this; }, _getHandle: function(event) { - - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; - $(this.options.handle, this.element) - .find("*") - .addBack() - .each(function() { - if(this === event.target) { - handle = true; - } - }); - - return handle; - + return this.options.handle ? + !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : + true; }, _createHelper: function(event) { var o = this.options, @@ -339,11 +328,10 @@ }, _getParentOffset: function() { //Get the offsetParent and cache its position - this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that @@ -400,98 +388,126 @@ _setContainment: function() { var over, c, ce, o = this.options; - if(o.containment === "parent") { - o.containment = this.helper[0].parentNode; + if ( !o.containment ) { + this.containment = null; + return; } - if(o.containment === "document" || o.containment === "window") { + + if ( o.containment === "window" ) { this.containment = [ - o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, - (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, - (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, + $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, + $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top ]; + return; } - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) { - c = $(o.containment); - ce = c[0]; - - if(!ce) { - return; - } - - over = ($(ce).css("overflow") !== "hidden"); - + if ( o.containment === "document") { this.containment = [ - (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), - (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), - (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, - (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 + 0, + 0, + $( document ).width() - this.helperProportions.width - this.margins.left, + ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top ]; - this.relative_container = c; + return; + } - } else if(o.containment.constructor === Array) { + if ( o.containment.constructor === Array ) { this.containment = o.containment; + return; } + if ( o.containment === "parent" ) { + o.containment = this.helper[ 0 ].parentNode; + } + + c = $( o.containment ); + ce = c[ 0 ]; + + if( !ce ) { + return; + } + + over = c.css( "overflow" ) !== "hidden"; + + this.containment = [ + ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), + ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom + ]; + this.relative_container = c; }, _convertPositionTo: function(d, pos) { if(!pos) { pos = this.position; } var mod = d === "absolute" ? 1 : -1, - 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); + scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; + //Cache the scroll + if (!this.offset.scroll) { + this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; + } + return { top: ( pos.top + // The absolute mouse position this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) ), left: ( pos.left + // The absolute mouse position this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) ) }; }, _generatePosition: function(event) { var containment, co, top, left, 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), + scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, pageX = event.pageX, pageY = event.pageY; + //Cache the scroll + if (!this.offset.scroll) { + this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; + } + /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ - if(this.originalPosition) { //If we are not dragging yet, we won't check for options - if(this.containment) { - if (this.relative_container){ - co = this.relative_container.offset(); - containment = [ this.containment[0] + co.left, - this.containment[1] + co.top, - this.containment[2] + co.left, - this.containment[3] + co.top ]; - } - else { - containment = this.containment; - } + // If we are not dragging yet, we won't check for options + if ( this.originalPosition ) { + if ( this.containment ) { + if ( this.relative_container ){ + co = this.relative_container.offset(); + containment = [ + this.containment[ 0 ] + co.left, + this.containment[ 1 ] + co.top, + this.containment[ 2 ] + co.left, + this.containment[ 3 ] + co.top + ]; + } + else { + containment = this.containment; + } if(event.pageX - this.offset.click.left < containment[0]) { pageX = containment[0] + this.offset.click.left; } if(event.pageY - this.offset.click.top < containment[1]) { @@ -520,18 +536,18 @@ top: ( pageY - // The absolute mouse position this.offset.click.top - // Click offset (relative to the element) this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) ), left: ( pageX - // The absolute mouse position this.offset.click.left - // Click offset (relative to the element) this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) ) }; }, @@ -602,11 +618,11 @@ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" if(this.shouldRevert) { - this.instance.options.revert = true; + this.instance.options.revert = this.shouldRevert; } //Trigger the stop of the sortable this.instance._mouseStop(event); @@ -645,11 +661,11 @@ this.instance.positionAbs = inst.positionAbs; this.instance.helperProportions = inst.helperProportions; this.instance.offset.click = inst.offset.click; if (this !== thisSortable && this.instance._intersectsWith(this.instance.containerCache) && - $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]) + $.contains(thisSortable.instance.element[0], this.instance.element[0]) ) { innermostIntersecting = false; } return innermostIntersecting; }); @@ -849,12 +865,11 @@ l = inst.snapElements[i].left; r = l + inst.snapElements[i].width; t = inst.snapElements[i].top; b = t + inst.snapElements[i].height; - //Yes, I know, this is insane ;) - 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))) { + if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { 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 }))); } inst.snapElements[i].snapping = false; continue; @@ -910,25 +925,22 @@ } }); $.ui.plugin.add("draggable", "stack", { start: function() { - var min, - o = $(this).data("ui-draggable").options, + o = this.data("ui-draggable").options, group = $.makeArray($(o.stack)).sort(function(a,b) { return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); }); if (!group.length) { return; } - min = parseInt(group[0].style.zIndex, 10) || 0; + min = parseInt($(group[0]).css("zIndex"), 10) || 0; $(group).each(function(i) { - this.style.zIndex = min + i; + $(this).css("zIndex", min + i); }); - - this[0].style.zIndex = min + group.length; - + this.css("zIndex", (min + group.length)); } }); $.ui.plugin.add("draggable", "zIndex", { start: function(event, ui) {