From e1f23184a662cdafa5a8152bcbc775da5e4ef726 Mon Sep 17 00:00:00 2001 From: Alexander Schmitz Date: Wed, 30 Mar 2016 22:11:22 -0400 Subject: [PATCH] Sortable: Fix line length issues Ref gh-1690 --- ui/widgets/sortable.js | 465 ++++++++++++++++++++++++++++++----------- 1 file changed, 345 insertions(+), 120 deletions(-) diff --git a/ui/widgets/sortable.js b/ui/widgets/sortable.js index ec26250b5..2a9ce22ca 100644 --- a/ui/widgets/sortable.js +++ b/ui/widgets/sortable.js @@ -82,7 +82,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { }, _isFloating: function( item ) { - return ( /left|right/ ).test( item.css( "float" ) ) || ( /inline|table-cell/ ).test( item.css( "display" ) ); + return ( /left|right/ ).test( item.css( "float" ) ) || + ( /inline|table-cell/ ).test( item.css( "display" ) ); }, _create: function() { @@ -190,7 +191,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.currentContainer = this; - //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + //We only need to call refreshPositions, because the refreshItems call has been moved to + // mouseCapture this.refreshPositions(); //Create and append the visible helper @@ -223,7 +225,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { top: event.pageY - this.offset.top }, parent: this._getParentOffset(), - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + + // This is a relative to absolute position minus the actual position calculation - + // only used for relative positioned helper + relative: this._getRelativeOffset() } ); // Only after we got the offset, we can change the helper's position to absolute @@ -240,9 +245,13 @@ return $.widget( "ui.sortable", $.ui.mouse, { ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) ); //Cache the former DOM position - this.domPosition = { prev: this.currentItem.prev()[ 0 ], parent: this.currentItem.parent()[ 0 ] }; + this.domPosition = { + prev: this.currentItem.prev()[ 0 ], + parent: this.currentItem.parent()[ 0 ] + }; - //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way + // If the helper is not the original, hide the original so it's not playing any role during + // the drag, won't cause anything bad this way if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) { this.currentItem.hide(); } @@ -262,7 +271,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.storedCursor = body.css( "cursor" ); body.css( "cursor", o.cursor ); - this.storedStylesheet = $( "" ).appendTo( body ); + this.storedStylesheet = + $( "" ).appendTo( body ); } if ( o.opacity ) { // opacity option @@ -280,7 +290,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { } //Prepare scrolling - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ].tagName !== "HTML" ) { + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { this.overflowOffset = this.scrollParent.offset(); } @@ -311,7 +322,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.dragging = true; this._addClass( this.helper, "ui-sortable-helper" ); - this._mouseDrag( event ); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + // Execute the drag once - this causes the helper not to be visiblebefore getting its + // correct position + this._mouseDrag( event ); return true; }, @@ -331,32 +345,45 @@ return $.widget( "ui.sortable", $.ui.mouse, { //Do scrolling if ( this.options.scroll ) { - if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ].tagName !== "HTML" ) { + if ( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ].tagName !== "HTML" ) { - if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - event.pageY < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; + if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) - + event.pageY < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollTop = scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; + this.scrollParent[ 0 ].scrollTop = + scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; } - if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - event.pageX < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; + if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) - + event.pageX < o.scrollSensitivity ) { + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) { - this.scrollParent[ 0 ].scrollLeft = scrolled = this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; + this.scrollParent[ 0 ].scrollLeft = scrolled = + this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; } } else { if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) { scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed ); - } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < o.scrollSensitivity ) { + } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) < + o.scrollSensitivity ) { scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed ); } if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( this.document.scrollLeft() - o.scrollSpeed ); - } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < o.scrollSensitivity ) { - scrolled = this.document.scrollLeft( this.document.scrollLeft() + o.scrollSpeed ); + scrolled = this.document.scrollLeft( + this.document.scrollLeft() - o.scrollSpeed + ); + } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) < + o.scrollSensitivity ) { + scrolled = this.document.scrollLeft( + this.document.scrollLeft() + o.scrollSpeed + ); } } @@ -405,7 +432,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { if ( itemElement !== this.currentItem[ 0 ] && this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement && !$.contains( this.placeholder[ 0 ], itemElement ) && - ( this.options.type === "semi-dynamic" ? !$.contains( this.element[ 0 ], itemElement ) : true ) + ( this.options.type === "semi-dynamic" ? + !$.contains( this.element[ 0 ], itemElement ) : + true + ) ) { this.direction = intersection === 1 ? "down" : "up"; @@ -455,15 +485,27 @@ return $.widget( "ui.sortable", $.ui.mouse, { animation = {}; if ( !axis || axis === "x" ) { - animation.left = cur.left - this.offset.parent.left - this.margins.left + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 0 : this.offsetParent[ 0 ].scrollLeft ); + animation.left = cur.left - this.offset.parent.left - this.margins.left + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollLeft + ); } if ( !axis || axis === "y" ) { - animation.top = cur.top - this.offset.parent.top - this.margins.top + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? 0 : this.offsetParent[ 0 ].scrollTop ); + animation.top = cur.top - this.offset.parent.top - this.margins.top + + ( this.offsetParent[ 0 ] === this.document[ 0 ].body ? + 0 : + this.offsetParent[ 0 ].scrollTop + ); } this.reverting = true; - $( this.helper ).animate( animation, parseInt( this.options.revert, 10 ) || 500, function() { - that._clear( event ); - } ); + $( this.helper ).animate( + animation, + parseInt( this.options.revert, 10 ) || 500, + function() { + that._clear( event ); + } + ); } else { this._clear( event, noPropagation ); } @@ -498,11 +540,13 @@ return $.widget( "ui.sortable", $.ui.mouse, { if ( this.placeholder ) { - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! if ( this.placeholder[ 0 ].parentNode ) { this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); } - if ( this.options.helper !== "original" && this.helper && this.helper[ 0 ].parentNode ) { + if ( this.options.helper !== "original" && this.helper && + this.helper[ 0 ].parentNode ) { this.helper.remove(); } @@ -531,9 +575,12 @@ return $.widget( "ui.sortable", $.ui.mouse, { o = o || {}; $( items ).each( function() { - var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ).match( o.expression || ( /(.+)[\-=_](.+)/ ) ); + var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" ) + .match( o.expression || ( /(.+)[\-=_](.+)/ ) ); if ( res ) { - str.push( ( o.key || res[ 1 ] + "[]" ) + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); + str.push( + ( o.key || res[ 1 ] + "[]" ) + + "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) ); } } ); @@ -552,7 +599,9 @@ return $.widget( "ui.sortable", $.ui.mouse, { o = o || {}; - items.each( function() { ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); } ); + items.each( function() { + ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" ); + } ); return ret; }, @@ -570,13 +619,17 @@ return $.widget( "ui.sortable", $.ui.mouse, { b = t + item.height, dyClick = this.offset.click.top, dxClick = this.offset.click.left, - isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), - isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), + isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && + ( y1 + dyClick ) < b ), + isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && + ( x1 + dxClick ) < r ), isOverElement = isOverElementHeight && isOverElementWidth; if ( this.options.tolerance === "pointer" || this.options.forcePointerForContainers || - ( this.options.tolerance !== "pointer" && this.helperProportions[ this.floating ? "width" : "height" ] > item[ this.floating ? "width" : "height" ] ) + ( this.options.tolerance !== "pointer" && + this.helperProportions[ this.floating ? "width" : "height" ] > + item[ this.floating ? "width" : "height" ] ) ) { return isOverElement; } else { @@ -590,10 +643,13 @@ return $.widget( "ui.sortable", $.ui.mouse, { }, _intersectsWithPointer: function( item ) { - var verticalDirection, horizontalDirection, - isOverElementHeight = ( this.options.axis === "x" ) || this._isOverAxis( this.positionAbs.top + this.offset.click.top, item.top, item.height ), - isOverElementWidth = ( this.options.axis === "y" ) || this._isOverAxis( this.positionAbs.left + this.offset.click.left, item.left, item.width ), + isOverElementHeight = ( this.options.axis === "x" ) || + this._isOverAxis( + this.positionAbs.top + this.offset.click.top, item.top, item.height ), + isOverElementWidth = ( this.options.axis === "y" ) || + this._isOverAxis( + this.positionAbs.left + this.offset.click.left, item.left, item.width ), isOverElement = isOverElementHeight && isOverElementWidth; if ( !isOverElement ) { @@ -611,15 +667,19 @@ return $.widget( "ui.sortable", $.ui.mouse, { _intersectsWithSides: function( item ) { - var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), - isOverRightHalf = this._isOverAxis( this.positionAbs.left + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), + var isOverBottomHalf = this._isOverAxis( this.positionAbs.top + + this.offset.click.top, item.top + ( item.height / 2 ), item.height ), + isOverRightHalf = this._isOverAxis( this.positionAbs.left + + this.offset.click.left, item.left + ( item.width / 2 ), item.width ), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if ( this.floating && horizontalDirection ) { - return ( ( horizontalDirection === "right" && isOverRightHalf ) || ( horizontalDirection === "left" && !isOverRightHalf ) ); + return ( ( horizontalDirection === "right" && isOverRightHalf ) || + ( horizontalDirection === "left" && !isOverRightHalf ) ); } else { - return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || ( verticalDirection === "up" && !isOverBottomHalf ) ); + return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) || + ( verticalDirection === "up" && !isOverBottomHalf ) ); } }, @@ -643,7 +703,9 @@ return $.widget( "ui.sortable", $.ui.mouse, { _connectWith: function() { var options = this.options; - return options.connectWith.constructor === String ? [ options.connectWith ] : options.connectWith; + return options.connectWith.constructor === String ? + [ options.connectWith ] : + options.connectWith; }, _getItemsAsjQuery: function( connected ) { @@ -659,13 +721,22 @@ return $.widget( "ui.sortable", $.ui.mouse, { for ( j = cur.length - 1; j >= 0; j-- ) { inst = $.data( cur[ j ], this.widgetFullName ); if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ $.isFunction( inst.options.items ) ? inst.options.items.call( inst.element ) : $( inst.options.items, inst.element ).not( ".ui-sortable-helper" ).not( ".ui-sortable-placeholder" ), inst ] ); + queries.push( [ $.isFunction( inst.options.items ) ? + inst.options.items.call( inst.element ) : + $( inst.options.items, inst.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), inst ] ); } } } } - queries.push( [ $.isFunction( this.options.items ) ? this.options.items.call( this.element, null, { options: this.options, item: this.currentItem } ) : $( this.options.items, this.element ).not( ".ui-sortable-helper" ).not( ".ui-sortable-placeholder" ), this ] ); + queries.push( [ $.isFunction( this.options.items ) ? + this.options.items + .call( this.element, null, { options: this.options, item: this.currentItem } ) : + $( this.options.items, this.element ) + .not( ".ui-sortable-helper" ) + .not( ".ui-sortable-placeholder" ), this ] ); function addItems() { items.push( this ); @@ -700,16 +771,22 @@ return $.widget( "ui.sortable", $.ui.mouse, { var i, j, cur, inst, targetData, _queries, item, queriesLength, items = this.items, - queries = [ [ $.isFunction( this.options.items ) ? this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : $( this.options.items, this.element ), this ] ], + queries = [ [ $.isFunction( this.options.items ) ? + this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) : + $( this.options.items, this.element ), this ] ], connectWith = this._connectWith(); - if ( connectWith && this.ready ) { //Shouldn't be run the first time through due to massive slow-down + //Shouldn't be run the first time through due to massive slow-down + if ( connectWith && this.ready ) { for ( i = connectWith.length - 1; i >= 0; i-- ) { cur = $( connectWith[ i ], this.document[ 0 ] ); for ( j = cur.length - 1; j >= 0; j-- ) { inst = $.data( cur[ j ], this.widgetFullName ); if ( inst && inst !== this && !inst.options.disabled ) { - queries.push( [ $.isFunction( inst.options.items ) ? inst.options.items.call( inst.element[ 0 ], event, { item: this.currentItem } ) : $( inst.options.items, inst.element ), inst ] ); + queries.push( [ $.isFunction( inst.options.items ) ? + inst.options.items + .call( inst.element[ 0 ], event, { item: this.currentItem } ) : + $( inst.options.items, inst.element ), inst ] ); this.containers.push( inst ); } } @@ -723,7 +800,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) { item = $( _queries[ j ] ); - item.data( this.widgetName + "-item", targetData ); // Data for target checking (mouse manager) + // Data for target checking (mouse manager) + item.data( this.widgetName + "-item", targetData ); items.push( { item: item, @@ -743,7 +821,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) : false; - //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change + //This has to be redone because due to the item being moved out/into the offsetParent, + // the offsetParent's position will change if ( this.offsetParent && this.helper ) { this.offset.parent = this._getParentOffset(); } @@ -754,11 +833,14 @@ return $.widget( "ui.sortable", $.ui.mouse, { item = this.items[ i ]; //We ignore calculating positions of all connected containers when we're not over them - if ( item.instance !== this.currentContainer && this.currentContainer && item.item[ 0 ] !== this.currentItem[ 0 ] ) { + if ( item.instance !== this.currentContainer && this.currentContainer && + item.item[ 0 ] !== this.currentItem[ 0 ] ) { continue; } - t = this.options.toleranceElement ? $( this.options.toleranceElement, item.item ) : item.item; + t = this.options.toleranceElement ? + $( this.options.toleranceElement, item.item ) : + item.item; if ( !fast ) { item.width = t.outerWidth(); @@ -777,8 +859,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { p = this.containers[ i ].element.offset(); this.containers[ i ].containerCache.left = p.left; this.containers[ i ].containerCache.top = p.top; - this.containers[ i ].containerCache.width = this.containers[ i ].element.outerWidth(); - this.containers[ i ].containerCache.height = this.containers[ i ].element.outerHeight(); + this.containers[ i ].containerCache.width = + this.containers[ i ].element.outerWidth(); + this.containers[ i ].containerCache.height = + this.containers[ i ].element.outerHeight(); } } @@ -821,15 +905,28 @@ return $.widget( "ui.sortable", $.ui.mouse, { }, update: function( container, p ) { - // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that - // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified + // 1. If a className is set as 'placeholder option, we don't force sizes - + // the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a + // class name is specified if ( className && !o.forcePlaceholderSize ) { return; } - //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item - if ( !p.height() ) { p.height( that.currentItem.innerHeight() - parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); } - if ( !p.width() ) { p.width( that.currentItem.innerWidth() - parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); } + //If the element doesn't have a actual height by itself (without styles coming + // from a stylesheet), it receives the inline height from the dragged item + if ( !p.height() ) { + p.height( + that.currentItem.innerHeight() - + parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) ); + } + if ( !p.width() ) { + p.width( + that.currentItem.innerWidth() - + parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) - + parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) ); + } } }; } @@ -856,7 +953,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { }, _contactContainers: function( event ) { - var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis, + var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, + floating, axis, innermostContainer = null, innermostIndex = null; @@ -871,7 +969,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { if ( this._intersectsWith( this.containers[ i ].containerCache ) ) { // If we've already found a container and it's more "inner" than this, then continue - if ( innermostContainer && $.contains( this.containers[ i ].element[ 0 ], innermostContainer.element[ 0 ] ) ) { + if ( innermostContainer && + $.contains( + this.containers[ i ].element[ 0 ], + innermostContainer.element[ 0 ] ) ) { continue; } @@ -902,7 +1003,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { } } else { - //When entering a new container, we will find the item with the least distance and append our item near it + // When entering a new container, we will find the item with the least distance and + // append our item near it dist = 10000; itemWithLeastDistance = null; floating = innermostContainer.floating || this._isFloating( this.currentItem ); @@ -911,7 +1013,9 @@ return $.widget( "ui.sortable", $.ui.mouse, { axis = floating ? "pageX" : "pageY"; for ( j = this.items.length - 1; j >= 0; j-- ) { - if ( !$.contains( this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) ) { + if ( !$.contains( + this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] ) + ) { continue; } if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) { @@ -944,7 +1048,9 @@ return $.widget( "ui.sortable", $.ui.mouse, { return; } - itemWithLeastDistance ? this._rearrange( event, itemWithLeastDistance, null, true ) : this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); + itemWithLeastDistance ? + this._rearrange( event, itemWithLeastDistance, null, true ) : + this._rearrange( event, null, this.containers[ innermostIndex ].element, true ); this._trigger( "change", event, this._uiHash() ); this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) ); this.currentContainer = this.containers[ innermostIndex ]; @@ -961,15 +1067,25 @@ return $.widget( "ui.sortable", $.ui.mouse, { _createHelper: function( event ) { var o = this.options, - helper = $.isFunction( o.helper ) ? $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); + helper = $.isFunction( o.helper ) ? + $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) : + ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem ); //Add the helper to the DOM if that didn't happen already if ( !helper.parents( "body" ).length ) { - $( o.appendTo !== "parent" ? o.appendTo : this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); + $( o.appendTo !== "parent" ? + o.appendTo : + this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] ); } if ( helper[ 0 ] === this.currentItem[ 0 ] ) { - this._storedCSS = { width: this.currentItem[ 0 ].style.width, height: this.currentItem[ 0 ].style.height, position: this.currentItem.css( "position" ), top: this.currentItem.css( "top" ), left: this.currentItem.css( "left" ) }; + this._storedCSS = { + width: this.currentItem[ 0 ].style.width, + height: this.currentItem[ 0 ].style.height, + position: this.currentItem.css( "position" ), + top: this.currentItem.css( "top" ), + left: this.currentItem.css( "left" ) + }; } if ( !helper[ 0 ].style.width || o.forceHelperSize ) { @@ -1010,18 +1126,24 @@ return $.widget( "ui.sortable", $.ui.mouse, { 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 - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { + // 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 the scroll is included in the initial calculation of the + // offset of the parent, and never recalculated upon drag + if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } - // This needs to be actually done for all browsers, since pageX/pageY includes this information - // with an ugly IE fix - if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || ( this.offsetParent[ 0 ].tagName && this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { + // This needs to be actually done for all browsers, since pageX/pageY includes this + // information with an ugly IE fix + if ( this.offsetParent[ 0 ] === this.document[ 0 ].body || + ( this.offsetParent[ 0 ].tagName && + this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) { po = { top: 0, left: 0 }; } @@ -1037,8 +1159,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { if ( this.cssPosition === "relative" ) { var p = this.currentItem.position(); return { - top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + this.scrollParent.scrollTop(), - left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + this.scrollParent.scrollLeft() + top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) + + this.scrollParent.scrollTop(), + left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) + + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; @@ -1071,8 +1195,13 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, - o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left, - ( o.containment === "document" ? ( this.document.height() || document.body.parentNode.scrollHeight ) : this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top + o.containment === "document" ? + this.document.width() : + this.window.width() - this.helperProportions.width - this.margins.left, + ( o.containment === "document" ? + ( this.document.height() || document.body.parentNode.scrollHeight ) : + this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight + ) - this.helperProportions.height - this.margins.top ]; } @@ -1082,10 +1211,18 @@ return $.widget( "ui.sortable", $.ui.mouse, { over = ( $( ce ).css( "overflow" ) !== "hidden" ); this.containment = [ - co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, - co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, - co.left + ( 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, - co.top + ( 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 + co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left, + co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) + + ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top, + co.left + ( 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, + co.top + ( 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 ]; } @@ -1097,21 +1234,41 @@ return $.widget( "ui.sortable", $.ui.mouse, { pos = this.position; } var mod = d === "absolute" ? 1 : -1, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, + scroll = this.cssPosition === "absolute" && + !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); 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 ) + + // The absolute mouse position + pos.top + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * 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 ) + + // The absolute mouse position + pos.left + + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left * mod + + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left * mod - + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : + scroll.scrollLeft() ) * mod ) ) }; @@ -1123,13 +1280,19 @@ return $.widget( "ui.sortable", $.ui.mouse, { o = this.options, pageX = event.pageX, pageY = event.pageY, - scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && $.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 ] !== this.document[ 0 ] && + $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? + this.offsetParent : + this.scrollParent, + scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName ); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative // 2. and the scroll parent is the document or similar to the offset parent // we have to refresh the relative offset during the scroll so there are no jumps - if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { + if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] && + this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) { this.offset.relative = this._getRelativeOffset(); } @@ -1156,29 +1319,63 @@ return $.widget( "ui.sortable", $.ui.mouse, { } if ( o.grid ) { - top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ]; - pageY = this.containment ? ( ( top - this.offset.click.top >= this.containment[ 1 ] && top - this.offset.click.top <= this.containment[ 3 ] ) ? top : ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top; + top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) / + o.grid[ 1 ] ) * o.grid[ 1 ]; + pageY = this.containment ? + ( ( top - this.offset.click.top >= this.containment[ 1 ] && + top - this.offset.click.top <= this.containment[ 3 ] ) ? + top : + ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ? + top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : + top; - left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ]; - pageX = this.containment ? ( ( left - this.offset.click.left >= this.containment[ 0 ] && left - this.offset.click.left <= this.containment[ 2 ] ) ? left : ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left; + left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) / + o.grid[ 0 ] ) * o.grid[ 0 ]; + pageX = this.containment ? + ( ( left - this.offset.click.left >= this.containment[ 0 ] && + left - this.offset.click.left <= this.containment[ 2 ] ) ? + left : + ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ? + left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : + left; } } return { 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() ) ) ) + + // The absolute mouse position + pageY - + + // Click offset (relative to the element) + this.offset.click.top - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.top - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.top + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollTop() : + ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) ) ), 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() ) ) + + // The absolute mouse position + pageX - + + // Click offset (relative to the element) + this.offset.click.left - + + // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.relative.left - + + // The offsetParent's offset without borders (offset + border) + this.offset.parent.left + + ( ( this.cssPosition === "fixed" ? + -this.scrollParent.scrollLeft() : + scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) ) }; @@ -1186,19 +1383,24 @@ return $.widget( "ui.sortable", $.ui.mouse, { _rearrange: function( event, i, a, hardRefresh ) { - a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); + a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) : + i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ], + ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) ); //Various things done here to improve the performance: // 1. we create a setTimeout, that calls refreshPositions // 2. on the instance, we have a counter variable, that get's higher after every append - // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same + // 3. on the local scope, we copy the counter variable, and check in the timeout, + // if it's still the same // 4. this lets only the last addition to the timeout stack through this.counter = this.counter ? ++this.counter : 1; var counter = this.counter; this._delay( function() { if ( counter === this.counter ) { - this.refreshPositions( !hardRefresh ); //Precompute after each DOM insertion, NOT on mousemove + + //Precompute after each DOM insertion, NOT on mousemove + this.refreshPositions( !hardRefresh ); } } ); @@ -1208,13 +1410,14 @@ return $.widget( "ui.sortable", $.ui.mouse, { this.reverting = false; - // We delay all events that have to be triggered to after the point where the placeholder has been removed and - // everything else normalized again + // We delay all events that have to be triggered to after the point where the placeholder + // has been removed and everything else normalized again var i, delayedTriggers = []; // We first have to update the dom position of the actual currentItem - // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) + // Note: don't do it if the current item is already removed (by a user), or it gets + // reappended (see #4088) if ( !this._noFinalSort && this.currentItem.parent().length ) { this.placeholder.before( this.currentItem ); } @@ -1233,19 +1436,38 @@ return $.widget( "ui.sortable", $.ui.mouse, { } if ( this.fromOutside && !noPropagation ) { - delayedTriggers.push( function( event ) { this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); } ); + delayedTriggers.push( function( event ) { + this._trigger( "receive", event, this._uiHash( this.fromOutside ) ); + } ); } - if ( ( this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { - delayedTriggers.push( function( event ) { this._trigger( "update", event, this._uiHash() ); } ); //Trigger update callback if the DOM position has changed + if ( ( this.fromOutside || + this.domPosition.prev !== + this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] || + this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) { + + // Trigger update callback if the DOM position has changed + delayedTriggers.push( function( event ) { + this._trigger( "update", event, this._uiHash() ); + } ); } // Check if the items Container has Changed and trigger appropriate // events. if ( this !== this.currentContainer ) { if ( !noPropagation ) { - delayedTriggers.push( function( event ) { this._trigger( "remove", event, this._uiHash() ); } ); - delayedTriggers.push( ( function( c ) { return function( event ) { c._trigger( "receive", event, this._uiHash( this ) ); }; } ).call( this, this.currentContainer ) ); - delayedTriggers.push( ( function( c ) { return function( event ) { c._trigger( "update", event, this._uiHash( this ) ); }; } ).call( this, this.currentContainer ) ); + delayedTriggers.push( function( event ) { + this._trigger( "remove", event, this._uiHash() ); + } ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "receive", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); + delayedTriggers.push( ( function( c ) { + return function( event ) { + c._trigger( "update", event, this._uiHash( this ) ); + }; + } ).call( this, this.currentContainer ) ); } } @@ -1283,7 +1505,8 @@ return $.widget( "ui.sortable", $.ui.mouse, { this._trigger( "beforeStop", event, this._uiHash() ); } - //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, + // it unbinds ALL events from the original node! this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] ); if ( !this.cancelHelperRemoval ) { @@ -1295,8 +1518,10 @@ return $.widget( "ui.sortable", $.ui.mouse, { if ( !noPropagation ) { for ( i = 0; i < delayedTriggers.length; i++ ) { + + // Trigger all delayed events delayedTriggers[ i ].call( this, event ); - } //Trigger all delayed events + } this._trigger( "stop", event, this._uiHash() ); }