|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
( function( factory ) { |
|
"use strict"; |
|
|
|
if ( typeof define === "function" && define.amd ) { |
|
|
|
|
|
define( [ |
|
"jquery", |
|
"./draggable", |
|
"./mouse", |
|
"../version", |
|
"../widget" |
|
], factory ); |
|
} else { |
|
|
|
|
|
factory( jQuery ); |
|
} |
|
} )( function( $ ) { |
|
"use strict"; |
|
|
|
$.widget( "ui.droppable", { |
|
version: "1.13.3", |
|
widgetEventPrefix: "drop", |
|
options: { |
|
accept: "*", |
|
addClasses: true, |
|
greedy: false, |
|
scope: "default", |
|
tolerance: "intersect", |
|
|
|
|
|
activate: null, |
|
deactivate: null, |
|
drop: null, |
|
out: null, |
|
over: null |
|
}, |
|
_create: function() { |
|
|
|
var proportions, |
|
o = this.options, |
|
accept = o.accept; |
|
|
|
this.isover = false; |
|
this.isout = true; |
|
|
|
this.accept = typeof accept === "function" ? accept : function( d ) { |
|
return d.is( accept ); |
|
}; |
|
|
|
this.proportions = function( ) { |
|
if ( arguments.length ) { |
|
|
|
|
|
proportions = arguments[ 0 ]; |
|
} else { |
|
|
|
|
|
return proportions ? |
|
proportions : |
|
proportions = { |
|
width: this.element[ 0 ].offsetWidth, |
|
height: this.element[ 0 ].offsetHeight |
|
}; |
|
} |
|
}; |
|
|
|
this._addToManager( o.scope ); |
|
|
|
if ( o.addClasses ) { |
|
this._addClass( "ui-droppable" ); |
|
} |
|
|
|
}, |
|
|
|
_addToManager: function( scope ) { |
|
|
|
|
|
$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; |
|
$.ui.ddmanager.droppables[ scope ].push( this ); |
|
}, |
|
|
|
_splice: function( drop ) { |
|
var i = 0; |
|
for ( ; i < drop.length; i++ ) { |
|
if ( drop[ i ] === this ) { |
|
drop.splice( i, 1 ); |
|
} |
|
} |
|
}, |
|
|
|
_destroy: function() { |
|
var drop = $.ui.ddmanager.droppables[ this.options.scope ]; |
|
|
|
this._splice( drop ); |
|
}, |
|
|
|
_setOption: function( key, value ) { |
|
|
|
if ( key === "accept" ) { |
|
this.accept = typeof value === "function" ? value : function( d ) { |
|
return d.is( value ); |
|
}; |
|
} else if ( key === "scope" ) { |
|
var drop = $.ui.ddmanager.droppables[ this.options.scope ]; |
|
|
|
this._splice( drop ); |
|
this._addToManager( value ); |
|
} |
|
|
|
this._super( key, value ); |
|
}, |
|
|
|
_activate: function( event ) { |
|
var draggable = $.ui.ddmanager.current; |
|
|
|
this._addActiveClass(); |
|
if ( draggable ) { |
|
this._trigger( "activate", event, this.ui( draggable ) ); |
|
} |
|
}, |
|
|
|
_deactivate: function( event ) { |
|
var draggable = $.ui.ddmanager.current; |
|
|
|
this._removeActiveClass(); |
|
if ( draggable ) { |
|
this._trigger( "deactivate", event, this.ui( draggable ) ); |
|
} |
|
}, |
|
|
|
_over: function( event ) { |
|
|
|
var draggable = $.ui.ddmanager.current; |
|
|
|
|
|
if ( !draggable || ( draggable.currentItem || |
|
draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
return; |
|
} |
|
|
|
if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || |
|
draggable.element ) ) ) { |
|
this._addHoverClass(); |
|
this._trigger( "over", event, this.ui( draggable ) ); |
|
} |
|
|
|
}, |
|
|
|
_out: function( event ) { |
|
|
|
var draggable = $.ui.ddmanager.current; |
|
|
|
|
|
if ( !draggable || ( draggable.currentItem || |
|
draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
return; |
|
} |
|
|
|
if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || |
|
draggable.element ) ) ) { |
|
this._removeHoverClass(); |
|
this._trigger( "out", event, this.ui( draggable ) ); |
|
} |
|
|
|
}, |
|
|
|
_drop: function( event, custom ) { |
|
|
|
var draggable = custom || $.ui.ddmanager.current, |
|
childrenIntersection = false; |
|
|
|
|
|
if ( !draggable || ( draggable.currentItem || |
|
draggable.element )[ 0 ] === this.element[ 0 ] ) { |
|
return false; |
|
} |
|
|
|
this.element |
|
.find( ":data(ui-droppable)" ) |
|
.not( ".ui-draggable-dragging" ) |
|
.each( function() { |
|
var inst = $( this ).droppable( "instance" ); |
|
if ( |
|
inst.options.greedy && |
|
!inst.options.disabled && |
|
inst.options.scope === draggable.options.scope && |
|
inst.accept.call( |
|
inst.element[ 0 ], ( draggable.currentItem || draggable.element ) |
|
) && |
|
$.ui.intersect( |
|
draggable, |
|
$.extend( inst, { offset: inst.element.offset() } ), |
|
inst.options.tolerance, event |
|
) |
|
) { |
|
childrenIntersection = true; |
|
return false; |
|
} |
|
} ); |
|
if ( childrenIntersection ) { |
|
return false; |
|
} |
|
|
|
if ( this.accept.call( this.element[ 0 ], |
|
( draggable.currentItem || draggable.element ) ) ) { |
|
this._removeActiveClass(); |
|
this._removeHoverClass(); |
|
|
|
this._trigger( "drop", event, this.ui( draggable ) ); |
|
return this.element; |
|
} |
|
|
|
return false; |
|
|
|
}, |
|
|
|
ui: function( c ) { |
|
return { |
|
draggable: ( c.currentItem || c.element ), |
|
helper: c.helper, |
|
position: c.position, |
|
offset: c.positionAbs |
|
}; |
|
}, |
|
|
|
|
|
|
|
_addHoverClass: function() { |
|
this._addClass( "ui-droppable-hover" ); |
|
}, |
|
|
|
_removeHoverClass: function() { |
|
this._removeClass( "ui-droppable-hover" ); |
|
}, |
|
|
|
_addActiveClass: function() { |
|
this._addClass( "ui-droppable-active" ); |
|
}, |
|
|
|
_removeActiveClass: function() { |
|
this._removeClass( "ui-droppable-active" ); |
|
} |
|
} ); |
|
|
|
$.ui.intersect = ( function() { |
|
function isOverAxis( x, reference, size ) { |
|
return ( x >= reference ) && ( x < ( reference + size ) ); |
|
} |
|
|
|
return function( draggable, droppable, toleranceMode, event ) { |
|
|
|
if ( !droppable.offset ) { |
|
return false; |
|
} |
|
|
|
var x1 = ( draggable.positionAbs || |
|
draggable.position.absolute ).left + draggable.margins.left, |
|
y1 = ( draggable.positionAbs || |
|
draggable.position.absolute ).top + draggable.margins.top, |
|
x2 = x1 + draggable.helperProportions.width, |
|
y2 = y1 + draggable.helperProportions.height, |
|
l = droppable.offset.left, |
|
t = droppable.offset.top, |
|
r = l + droppable.proportions().width, |
|
b = t + droppable.proportions().height; |
|
|
|
switch ( toleranceMode ) { |
|
case "fit": |
|
return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); |
|
case "intersect": |
|
return ( l < x1 + ( draggable.helperProportions.width / 2 ) && |
|
x2 - ( draggable.helperProportions.width / 2 ) < r && |
|
t < y1 + ( draggable.helperProportions.height / 2 ) && |
|
y2 - ( draggable.helperProportions.height / 2 ) < b ); |
|
case "pointer": |
|
return isOverAxis( event.pageY, t, droppable.proportions().height ) && |
|
isOverAxis( event.pageX, l, droppable.proportions().width ); |
|
case "touch": |
|
return ( |
|
( y1 >= t && y1 <= b ) || |
|
( y2 >= t && y2 <= b ) || |
|
( y1 < t && y2 > b ) |
|
) && ( |
|
( x1 >= l && x1 <= r ) || |
|
( x2 >= l && x2 <= r ) || |
|
( x1 < l && x2 > r ) |
|
); |
|
default: |
|
return false; |
|
} |
|
}; |
|
} )(); |
|
|
|
|
|
|
|
|
|
$.ui.ddmanager = { |
|
current: null, |
|
droppables: { "default": [] }, |
|
prepareOffsets: function( t, event ) { |
|
|
|
var i, j, |
|
m = $.ui.ddmanager.droppables[ t.options.scope ] || [], |
|
type = event ? event.type : null, |
|
list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); |
|
|
|
droppablesLoop: for ( i = 0; i < m.length; i++ ) { |
|
|
|
|
|
if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], |
|
( t.currentItem || t.element ) ) ) ) { |
|
continue; |
|
} |
|
|
|
|
|
for ( j = 0; j < list.length; j++ ) { |
|
if ( list[ j ] === m[ i ].element[ 0 ] ) { |
|
m[ i ].proportions().height = 0; |
|
continue droppablesLoop; |
|
} |
|
} |
|
|
|
m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; |
|
if ( !m[ i ].visible ) { |
|
continue; |
|
} |
|
|
|
|
|
if ( type === "mousedown" ) { |
|
m[ i ]._activate.call( m[ i ], event ); |
|
} |
|
|
|
m[ i ].offset = m[ i ].element.offset(); |
|
m[ i ].proportions( { |
|
width: m[ i ].element[ 0 ].offsetWidth, |
|
height: m[ i ].element[ 0 ].offsetHeight |
|
} ); |
|
|
|
} |
|
|
|
}, |
|
drop: function( draggable, event ) { |
|
|
|
var dropped = false; |
|
|
|
|
|
$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { |
|
|
|
if ( !this.options ) { |
|
return; |
|
} |
|
if ( !this.options.disabled && this.visible && |
|
$.ui.intersect( draggable, this, this.options.tolerance, event ) ) { |
|
dropped = this._drop.call( this, event ) || dropped; |
|
} |
|
|
|
if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], |
|
( draggable.currentItem || draggable.element ) ) ) { |
|
this.isout = true; |
|
this.isover = false; |
|
this._deactivate.call( this, event ); |
|
} |
|
|
|
} ); |
|
return dropped; |
|
|
|
}, |
|
dragStart: function( draggable, event ) { |
|
|
|
|
|
|
|
draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() { |
|
if ( !draggable.options.refreshPositions ) { |
|
$.ui.ddmanager.prepareOffsets( draggable, event ); |
|
} |
|
} ); |
|
}, |
|
drag: function( draggable, event ) { |
|
|
|
|
|
|
|
if ( draggable.options.refreshPositions ) { |
|
$.ui.ddmanager.prepareOffsets( draggable, event ); |
|
} |
|
|
|
|
|
$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { |
|
|
|
if ( this.options.disabled || this.greedyChild || !this.visible ) { |
|
return; |
|
} |
|
|
|
var parentInstance, scope, parent, |
|
intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), |
|
c = !intersects && this.isover ? |
|
"isout" : |
|
( intersects && !this.isover ? "isover" : null ); |
|
if ( !c ) { |
|
return; |
|
} |
|
|
|
if ( this.options.greedy ) { |
|
|
|
|
|
scope = this.options.scope; |
|
parent = this.element.parents( ":data(ui-droppable)" ).filter( function() { |
|
return $( this ).droppable( "instance" ).options.scope === scope; |
|
} ); |
|
|
|
if ( parent.length ) { |
|
parentInstance = $( parent[ 0 ] ).droppable( "instance" ); |
|
parentInstance.greedyChild = ( c === "isover" ); |
|
} |
|
} |
|
|
|
|
|
if ( parentInstance && c === "isover" ) { |
|
parentInstance.isover = false; |
|
parentInstance.isout = true; |
|
parentInstance._out.call( parentInstance, event ); |
|
} |
|
|
|
this[ c ] = true; |
|
this[ c === "isout" ? "isover" : "isout" ] = false; |
|
this[ c === "isover" ? "_over" : "_out" ].call( this, event ); |
|
|
|
|
|
if ( parentInstance && c === "isout" ) { |
|
parentInstance.isout = false; |
|
parentInstance.isover = true; |
|
parentInstance._over.call( parentInstance, event ); |
|
} |
|
} ); |
|
|
|
}, |
|
dragStop: function( draggable, event ) { |
|
draggable.element.parentsUntil( "body" ).off( "scroll.droppable" ); |
|
|
|
|
|
|
|
if ( !draggable.options.refreshPositions ) { |
|
$.ui.ddmanager.prepareOffsets( draggable, event ); |
|
} |
|
} |
|
}; |
|
|
|
|
|
|
|
if ( $.uiBackCompat !== false ) { |
|
|
|
|
|
$.widget( "ui.droppable", $.ui.droppable, { |
|
options: { |
|
hoverClass: false, |
|
activeClass: false |
|
}, |
|
_addActiveClass: function() { |
|
this._super(); |
|
if ( this.options.activeClass ) { |
|
this.element.addClass( this.options.activeClass ); |
|
} |
|
}, |
|
_removeActiveClass: function() { |
|
this._super(); |
|
if ( this.options.activeClass ) { |
|
this.element.removeClass( this.options.activeClass ); |
|
} |
|
}, |
|
_addHoverClass: function() { |
|
this._super(); |
|
if ( this.options.hoverClass ) { |
|
this.element.addClass( this.options.hoverClass ); |
|
} |
|
}, |
|
_removeHoverClass: function() { |
|
this._super(); |
|
if ( this.options.hoverClass ) { |
|
this.element.removeClass( this.options.hoverClass ); |
|
} |
|
} |
|
} ); |
|
} |
|
|
|
return $.ui.droppable; |
|
|
|
} ); |
|
|