@ -116,8 +116,10 @@ export class DropLocationDeterminer<T, NodeType extends SortableTreeNode<T>> ext
const { targetNode : lastTargetNode } = this . lastMoveData ;
this . eventHandlers . onMouseMove ? . ( mouseEvent ) ;
const { mouseXRelativeToContainer : mouseX , mouseYRelativeToContainer : mouseY } =
this . getMousePositionRelativeToContainer ( mouseEvent ) ;
const { mouseXRelative : mouseX , mouseYRelative : mouseY } = this . getMousePositionRelativeToContainer (
mouseEvent . clientX ,
mouseEvent . clientY ,
) ;
const targetNode = this . getTargetNode ( mouseEvent ) ;
const targetChanged = ! targetNode ? . equals ( lastTargetNode ) ;
if ( targetChanged ) {
@ -257,6 +259,10 @@ export class DropLocationDeterminer<T, NodeType extends SortableTreeNode<T>> ext
* /
private getTargetNode ( mouseEvent : MouseEvent ) : NodeType | undefined {
this . cacheContainerPosition ( this . containerContext . container ) ;
const { mouseXRelative , mouseYRelative } = this . getMousePositionRelativeToContainer (
mouseEvent . clientX ,
mouseEvent . clientY ,
) ;
// Get the element under the mouse
const mouseTargetEl = this . getMouseTargetElement ( mouseEvent ) ;
@ -268,10 +274,10 @@ export class DropLocationDeterminer<T, NodeType extends SortableTreeNode<T>> ext
let hoveredNode = this . getOrCreateHoveredNode ( hoveredModel ) ;
// Get the drop position index based on the mouse position
const { index } = this . getDropPosition ( hoveredNode , mouseEvent . clientX , mouseEvent . clientY ) ;
const { index } = this . getDropPosition ( hoveredNode , mouseXRelative , mouseYRelative ) ;
// Determine the valid target node (or its valid parent)
let targetNode = this . getValidParent ( hoveredNode , index , mouseEvent . clientX , mouseEvent . clientY ) ;
let targetNode = this . getValidParent ( hoveredNode , index , mouseXRelative , mouseYRelative ) ;
return this . getOrReuseTargetNode ( targetNode ) ;
}
@ -389,21 +395,44 @@ export class DropLocationDeterminer<T, NodeType extends SortableTreeNode<T>> ext
private getValidParent ( targetNode : NodeType , index : number , mouseX : number , mouseY : number ) : NodeType | undefined {
if ( ! targetNode ) return ;
const positionNotChanged = targetNode . equals ( this . lastMoveData . targetNode ) && index === this . lastMoveData . index ;
if ( positionNotChanged ) return targetNode ;
const lastTargetNode = this . lastMoveData . targetNode ;
const targetNotChanged = targetNode . equals ( lastTargetNode ) ;
targetNode . nodeDimensions = targetNotChanged ? lastTargetNode . nodeDimensions ! : this . getDim ( targetNode . element ! ) ;
if ( ! targetNode . isWithinDropBounds ( mouseX , mouseY ) ) {
return this . handleParentTraversal ( targetNode , mouseX , mouseY ) ;
}
const positionNotChanged = targetNotChanged && index === this . lastMoveData . index ;
if ( positionNotChanged ) return lastTargetNode ;
const canMove = this . sourceNodes . some ( ( node ) = > targetNode . canMove ( node , index ) ) ;
this . triggerDragValidation ( canMove , targetNode ) ;
if ( canMove ) return targetNode ;
return this . handleParentTraversal ( targetNode , mouseX , mouseY ) ;
}
private handleParentTraversal ( targetNode : NodeType , mouseX : number , mouseY : number ) : NodeType | undefined {
const parent = targetNode . getParent ( ) as NodeType ;
if ( ! parent ) return ;
const indexInParent = this . getIndexInParent ( parent , targetNode , targetNode . nodeDimensions ! , mouseX , mouseY ) ;
return this . getValidParent ( parent , indexInParent , mouseX , mouseY ) ;
}
private getIndexInParent (
parent : NodeType ,
targetNode : NodeType ,
nodeDimensions : Dimension ,
mouseX : number ,
mouseY : number ,
) {
let indexInParent = parent ? . indexOfChild ( targetNode ) ;
const nodeDimensions = this . getDim ( targetNode . element ! ) ;
nodeDimensions . dir = this . getDirection ( targetNode . element ! , parent . element ! ) ;
indexInParent = indexInParent + ( nodeDimensions . determinePlacement ( mouseX , mouseY ) == 'after' ? 1 : 0 ) ;
return this . getValidParent ( parent , indexInParent , mouseX , mouseY ) ;
return indexInParent ;
}
private triggerDragValidation ( canMove : boolean , targetNode : NodeType ) {
@ -488,27 +517,26 @@ export class DropLocationDeterminer<T, NodeType extends SortableTreeNode<T>> ext
/ * *
* Gets the mouse position relative to the container , adjusting for scroll and canvas relative options .
*
* @param { MouseEvent } mouseEvent - The current mouse event .
* @return { { mouseXRelativeToContainer : number , mouseYRelativeToContainer : number } } - The mouse X and Y positions relative to the container .
* @private
* /
private getMousePositionRelativeToContainer ( mouseEvent : MouseEvent ) : {
mouseXRelativeToContainer : number ;
mouseYRelativeToContainer : number ;
private getMousePositionRelativeToContainer (
mouseX : number ,
mouseY : number ,
) : {
mouseXRelative : number ;
mouseYRelative : number ;
} {
const { em } = this ;
let mouseYRelativeToContainer =
mouseEvent . pageY - this . containerOffset . top + this . containerContext . container . scrollTop ;
let mouseXRelativeToContainer =
mouseEvent . pageX - this . containerOffset . left + this . containerContext . container . scrollLeft ;
if ( this . positionOptions . canvasRelative && ! ! em ) {
const mousePos = em . Canvas . getMouseRelativeCanvas ( mouseEvent , { noScroll : 1 } ) ;
mouseXRelativeToContainer = mousePos . x ;
mouseYRelativeToContainer = mousePos . y ;
let mouseYRelative = mouseY - this . containerOffset . top + this . containerContext . container . scrollTop ;
let mouseXRelative = mouseX - this . containerOffset . left + this . containerContext . container . scrollLeft ;
if ( this . positionOptions . canvasRelative ) {
const mousePos = this . em . Canvas . getMouseRelativeCanvas ( { clientX : mouseX , clientY : mouseY } , { noScroll : 1 } ) ;
mouseXRelative = mousePos . x ;
mouseYRelative = mousePos . y ;
}
return { mouseXRelativeToContainer , mouseYRelativeToContainer } ;
return { mouseXRelative , mouseYRelative } ;
}
/ * *