@@ -10,7 +10,8 @@ import {
1010 setRect ,
1111 unsetRect ,
1212 matrix ,
13- expando
13+ expando ,
14+ getParentOrHost ,
1415} from '../../src/utils.js' ;
1516
1617import dispatchEvent from '../../src/EventDispatcher.js' ;
@@ -19,6 +20,7 @@ let multiDragElements = [],
1920 multiDragClones = [ ] ,
2021 lastMultiDragSelect , // for selection with modifier key down (SHIFT)
2122 multiDragSortable ,
23+ multiDragGroupMembers = { } ,
2224 initialFolding = false , // Initial multi-drag fold when drag started
2325 folding = false , // Folding any other time
2426 dragStarted = false ,
@@ -44,6 +46,14 @@ function MultiDragPlugin() {
4446 }
4547 }
4648
49+ if ( sortable . options . group ) {
50+ const group = typeof sortable . options . group === 'string' ? { name : sortable . options . group } : sortable . options . group ;
51+ if ( multiDragGroupMembers [ group . name ] === undefined ) {
52+ multiDragGroupMembers [ group . name ] = [ ] ;
53+ }
54+ multiDragGroupMembers [ group . name ] . push ( sortable ) ;
55+ }
56+
4757 on ( document , 'keydown' , this . _checkKeyDown ) ;
4858 on ( document , 'keyup' , this . _checkKeyUp ) ;
4959
@@ -69,7 +79,6 @@ function MultiDragPlugin() {
6979 multiDragKeyDown : false ,
7080 isMultiDrag : false ,
7181
72-
7382 delayStartGlobal ( { dragEl : dragged } ) {
7483 dragEl = dragged ;
7584 } ,
@@ -84,6 +93,7 @@ function MultiDragPlugin() {
8493 multiDragClones . push ( clone ( multiDragElements [ i ] ) ) ;
8594
8695 multiDragClones [ i ] . sortableIndex = multiDragElements [ i ] . sortableIndex ;
96+ multiDragClones [ i ] . sortableParentEl = multiDragElements [ i ] . sortableParentEl ;
8797
8898 multiDragClones [ i ] . draggable = false ;
8999 multiDragClones [ i ] . style [ 'will-change' ] = '' ;
@@ -136,11 +146,12 @@ function MultiDragPlugin() {
136146
137147 dragStartGlobal ( { sortable } ) {
138148 if ( ! this . isMultiDrag && multiDragSortable ) {
139- multiDragSortable . multiDrag . _deselectMultiDrag ( ) ;
149+ MultiDrag . utils . clear ( ) ;
140150 }
141151
142152 multiDragElements . forEach ( multiDragElement => {
143153 multiDragElement . sortableIndex = index ( multiDragElement ) ;
154+ multiDragElement . sortableParentEl = getParentOrHost ( multiDragElement ) ;
144155 } ) ;
145156
146157 // Sort multi-drag elements
@@ -197,10 +208,46 @@ function MultiDragPlugin() {
197208 } ) ;
198209 } ,
199210
200- dragOver ( { target, completed, cancel } ) {
211+ dragOver ( { target, completed, cancel, originalEvent } ) {
201212 if ( folding && ~ multiDragElements . indexOf ( target ) ) {
202213 completed ( false ) ;
203214 cancel ( ) ;
215+ return ;
216+ }
217+
218+ const toSortable = target . parentNode [ expando ] ;
219+
220+ if ( ! toSortable || multiDragElements . length === 0 ) {
221+ return ;
222+ }
223+
224+ let checkPut ;
225+
226+ if ( toSortable . options . group ) {
227+ checkPut = toSortable . options . group . checkPut ;
228+ }
229+
230+ const forbiddenMove = ~ multiDragElements . findIndex ( ( el ) => {
231+ if ( ! el . sortableParentEl ) {
232+ return false ;
233+ }
234+
235+ const fromSortable = el . sortableParentEl [ expando ] ;
236+
237+ if ( fromSortable && fromSortable . options . group && ! fromSortable . options . group . checkPull ( toSortable , fromSortable , el , originalEvent ) ) {
238+ return true ;
239+ }
240+
241+ if ( checkPut && ! checkPut ( toSortable , fromSortable , el , originalEvent ) ) {
242+ return true ;
243+ }
244+
245+ return false ;
246+ } ) ;
247+
248+ if ( forbiddenMove ) {
249+ completed ( false ) ;
250+ cancel ( ) ;
204251 }
205252 } ,
206253
@@ -311,7 +358,7 @@ function MultiDragPlugin() {
311358 // Multi-drag selection
312359 if ( ! dragStarted ) {
313360 if ( options . multiDragKey && ! this . multiDragKeyDown ) {
314- this . _deselectMultiDrag ( ) ;
361+ MultiDrag . utils . clear ( ) ;
315362 }
316363 toggleClass ( dragEl , options . selectedClass , ! ~ multiDragElements . indexOf ( dragEl ) ) ;
317364
@@ -461,39 +508,38 @@ function MultiDragPlugin() {
461508 } ,
462509
463510 destroyGlobal ( ) {
464- this . _deselectMultiDrag ( ) ;
511+ MultiDrag . utils . clear ( ) ;
512+
465513 off ( document , 'pointerup' , this . _deselectMultiDrag ) ;
466514 off ( document , 'mouseup' , this . _deselectMultiDrag ) ;
467515 off ( document , 'touchend' , this . _deselectMultiDrag ) ;
468516
469517 off ( document , 'keydown' , this . _checkKeyDown ) ;
470518 off ( document , 'keyup' , this . _checkKeyUp ) ;
519+
520+ const groupMembers = findAllMembersInSortableGroup ( this . sortable ) ;
521+
522+ if ( groupMembers ) {
523+ let membersIndex ;
524+ if ( ~ ( membersIndex = groupMembers . indexOf ( this . sortable ) ) ) {
525+ groupMembers . splice ( membersIndex , 1 ) ;
526+ }
527+ }
471528 } ,
472529
473530 _deselectMultiDrag ( evt ) {
474- if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
475-
476531 // Only deselect if selection is in this sortable
477532 if ( multiDragSortable !== this . sortable ) return ;
478533
479- // Only deselect if target is not item in this sortable
480- if ( evt && closest ( evt . target , this . options . draggable , this . sortable . el , false ) ) return ;
481-
482- // Only deselect if left click
483- if ( evt && evt . button !== 0 ) return ;
484-
485- while ( multiDragElements . length ) {
486- let el = multiDragElements [ 0 ] ;
487- toggleClass ( el , this . options . selectedClass , false ) ;
488- multiDragElements . shift ( ) ;
489- dispatchEvent ( {
490- sortable : this . sortable ,
491- rootEl : this . sortable . el ,
492- name : 'deselect' ,
493- targetEl : el ,
494- originalEvent : evt
495- } ) ;
534+ if ( evt ) {
535+ // Only deselect if left click
536+ if ( evt . button !== 0 ) return ;
537+
538+ // Only deselect if target is not item in any sortable in group (including this)
539+ if ( itemElIsInSortableGroup ( evt . target , this . sortable ) ) return ;
496540 }
541+
542+ MultiDrag . utils . clear ( evt ) ;
497543 } ,
498544
499545 _checkKeyDown ( evt ) {
@@ -521,7 +567,9 @@ function MultiDragPlugin() {
521567 let sortable = el . parentNode [ expando ] ;
522568 if ( ! sortable || ! sortable . options . multiDrag || ~ multiDragElements . indexOf ( el ) ) return ;
523569 if ( multiDragSortable && multiDragSortable !== sortable ) {
524- multiDragSortable . multiDrag . _deselectMultiDrag ( ) ;
570+ if ( ! itemElIsInSortableGroup ( el , multiDragSortable ) ) {
571+ MultiDrag . utils . clear ( ) ;
572+ }
525573 multiDragSortable = sortable ;
526574 }
527575 toggleClass ( el , sortable . options . selectedClass , true ) ;
@@ -537,6 +585,24 @@ function MultiDragPlugin() {
537585 if ( ! sortable || ! sortable . options . multiDrag || ! ~ index ) return ;
538586 toggleClass ( el , sortable . options . selectedClass , false ) ;
539587 multiDragElements . splice ( index , 1 ) ;
588+ } ,
589+ clear ( evt ) {
590+ if ( typeof dragStarted !== "undefined" && dragStarted ) return ;
591+
592+ while ( multiDragElements . length ) {
593+ const el = multiDragElements [ 0 ] ;
594+ const sortableEl = getParentOrHost ( el ) ;
595+ const sortable = sortableEl [ expando ] ;
596+ toggleClass ( el , sortable . options . selectedClass , false ) ;
597+ multiDragElements . shift ( ) ;
598+ dispatchEvent ( {
599+ sortable : sortable ,
600+ rootEl : sortableEl ,
601+ name : 'deselect' ,
602+ targetEl : el ,
603+ originalEvent : evt
604+ } ) ;
605+ }
540606 }
541607 } ,
542608 eventProperties ( ) {
@@ -546,6 +612,7 @@ function MultiDragPlugin() {
546612 multiDragElements . forEach ( multiDragElement => {
547613 oldIndicies . push ( {
548614 multiDragElement,
615+ parentElement : multiDragElement . sortableParentEl ,
549616 index : multiDragElement . sortableIndex
550617 } ) ;
551618
@@ -560,9 +627,11 @@ function MultiDragPlugin() {
560627 }
561628 newIndicies . push ( {
562629 multiDragElement,
630+ parentElement : multiDragElement . sortableParentEl ,
563631 index : newIndex
564632 } ) ;
565633 } ) ;
634+
566635 return {
567636 items : [ ...multiDragElements ] ,
568637 clones : [ ...multiDragClones ] ,
@@ -572,11 +641,13 @@ function MultiDragPlugin() {
572641 } ,
573642 optionListeners : {
574643 multiDragKey ( key ) {
575- key = key . toLowerCase ( ) ;
576- if ( key === 'ctrl' ) {
577- key = 'Control' ;
578- } else if ( key . length > 1 ) {
579- key = key . charAt ( 0 ) . toUpperCase ( ) + key . substr ( 1 ) ;
644+ if ( typeof key === 'string' ) {
645+ key = key . toLowerCase ( ) ;
646+ if ( key === 'ctrl' ) {
647+ key = 'Control' ;
648+ } else if ( key . length > 1 ) {
649+ key = key . charAt ( 0 ) . toUpperCase ( ) + key . substr ( 1 ) ;
650+ }
580651 }
581652 return key ;
582653 }
@@ -618,4 +689,15 @@ function removeMultiDragElements() {
618689 } ) ;
619690}
620691
692+ function findAllMembersInSortableGroup ( sortable ) {
693+ if ( ! sortable . options . group ) {
694+ return null ;
695+ }
696+ return multiDragGroupMembers [ sortable . options . group . name ] || [ ] ;
697+ }
698+
699+ function itemElIsInSortableGroup ( itemEl , sortable ) {
700+ return ~ ( findAllMembersInSortableGroup ( sortable ) || [ sortable ] ) . findIndex ( ( sortable ) => closest ( itemEl , sortable . options . draggable , sortable . el , false ) ) ;
701+ }
702+
621703export default MultiDragPlugin ;
0 commit comments