@@ -341,24 +341,6 @@ describe('dndList', function() {
341
341
var dragenter = Dragenter . externalOn ( element , { 'application/x-dnd' : 'Lorem ipsum' } ) ;
342
342
verifyDropCancelled ( dragenter . dragover ( element ) . drop ( element ) , element , true , 3 ) ;
343
343
} ) ;
344
-
345
- describe ( 'dropEffect calculation' , function ( ) {
346
- testDropEffect ( 'move' , 'move' ) ;
347
- testDropEffect ( 'blub' , 'blub' ) ;
348
- testDropEffect ( 'copy' , 'none' , 'copy' ) ;
349
- testDropEffect ( 'move' , 'none' , 'move' ) ;
350
- testDropEffect ( 'move' , 'none' , 'link' ) ;
351
- testDropEffect ( 'copy' , 'none' , 'link' , true ) ;
352
-
353
- function testDropEffect ( expected , dropEffect , effectAllowed , ctrlKey ) {
354
- it ( 'stores ' + expected + ' for ' + [ dropEffect , effectAllowed , ctrlKey ] , function ( ) {
355
- var src = compileAndLink ( '<div dnd-draggable="{}" dnd-dragend="eff = dropEffect"></div>' ) ;
356
- var options = { dropEffect : dropEffect , effectAllowed : effectAllowed , ctrlKey : ctrlKey } ;
357
- Dragstart . on ( src ) . dragover ( element , options ) . drop ( element ) . dragend ( src ) ;
358
- expect ( src . scope ( ) . eff ) . toBe ( expected ) ;
359
- } ) ;
360
- }
361
- } ) ;
362
344
} ) ;
363
345
364
346
describe ( 'dragleave handler' , function ( ) {
@@ -399,6 +381,121 @@ describe('dndList', function() {
399
381
} ) ) ;
400
382
} ) ;
401
383
384
+ describe ( 'dropEffect' , function ( ) {
385
+ // This matrix shows the expected drop effect, given two effectAllowed values.
386
+ var ALL = [ 'all' , 'move' , 'copy' , 'link' , 'copyLink' , 'copyMove' , 'linkMove' ] ;
387
+ var EXPECTED_MATRIX = {
388
+ move : [ 'move' , 'move' , 'none' , 'none' , 'none' , 'move' , 'move' ] ,
389
+ copy : [ 'copy' , 'none' , 'copy' , 'none' , 'copy' , 'copy' , 'none' ] ,
390
+ link : [ 'link' , 'none' , 'none' , 'link' , 'link' , 'none' , 'link' ] ,
391
+ copyLink : [ 'copy' , 'none' , 'copy' , 'link' , 'copy' , 'copy' , 'link' ] ,
392
+ copyMove : [ 'move' , 'move' , 'copy' , 'none' , 'copy' , 'move' , 'move' ] ,
393
+ linkMove : [ 'move' , 'move' , 'none' , 'link' , 'link' , 'move' , 'move' ] ,
394
+ all : [ 'move' , 'move' , 'copy' , 'link' , 'copy' , 'move' , 'move' ] ,
395
+ '' : [ 'move' , 'move' , 'copy' , 'link' , 'copy' , 'move' , 'move' ] ,
396
+ } ;
397
+ angular . forEach ( ALL , function ( sourceEffectAllowed , index ) {
398
+ angular . forEach ( EXPECTED_MATRIX , function ( expected , targetEffectAllowed ) {
399
+ expected = expected [ index ] ;
400
+ it ( 'is ' + expected + ' for effect-allowed ' + sourceEffectAllowed
401
+ + ' and ' + targetEffectAllowed , function ( ) {
402
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-dragend="result = dropEffect" '
403
+ + 'dnd-effect-allowed="' + sourceEffectAllowed + '"></div>' ) ;
404
+ var target = createListWithItemsAndCallbacks ( false , targetEffectAllowed ) ;
405
+ expect ( Dragstart . on ( src ) . effectAllowed ) . toBe ( sourceEffectAllowed ) ;
406
+ if ( expected != 'none' ) {
407
+ // Verify dragover.
408
+ expect ( Dragstart . on ( src ) . dragover ( target ) . dropEffect ) . toBe ( expected ) ;
409
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( expected ) ;
410
+ // Verify drop.
411
+ expect ( Dragstart . on ( src ) . dragover ( target ) . drop ( target ) . dropEffect ) . toBe ( expected ) ;
412
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( expected ) ;
413
+ // Verify dragend.
414
+ Dragstart . on ( src ) . dragover ( target ) . drop ( target ) . dragend ( src ) ;
415
+ expect ( src . scope ( ) . result ) . toBe ( expected ) ;
416
+ } else {
417
+ verifyDropCancelled ( Dragstart . on ( src ) . dragover ( target ) , target , false , 3 ) ;
418
+ verifyDropCancelled ( Dragstart . on ( src ) . dragover ( target ) . drop ( target ) , target , true , 3 ) ;
419
+ Dragstart . on ( src ) . dragend ( src ) ;
420
+ expect ( src . scope ( ) . result ) . toBe ( 'none' ) ;
421
+ }
422
+ } ) ;
423
+ } ) ;
424
+ } ) ;
425
+
426
+ // In Safari dataTransfer.effectAllowed is always 'all', ignoring the value set in dragstart.
427
+ it ( 'is determined from internal state in Safari' , function ( ) {
428
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="link"></div>' ) ;
429
+ var target = createListWithItemsAndCallbacks ( false , 'copyLink' ) ;
430
+ var options = { effectAllowed : 'all' } ;
431
+ Dragstart . on ( src ) . dragover ( target , options ) . drop ( target , options ) ;
432
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'link' ) ;
433
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'link' ) ;
434
+ } ) ;
435
+
436
+ // On MacOS, modifiers automatically limit the effectAllowed passed to dragover and drop.
437
+ it ( 'is limited by modifier keys on MacOS' , function ( ) {
438
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="all"></div>' ) ;
439
+ var target = createListWithItemsAndCallbacks ( ) ;
440
+ Dragstart . on ( src ) . dragover ( target , { effectAllowed : 'copyLink' } ) . drop ( target ) ;
441
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'copy' ) ;
442
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'copy' ) ;
443
+ } ) ;
444
+
445
+ it ( 'is copy if Ctrl key is pressed' , function ( ) {
446
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="all"></div>' ) ;
447
+ var target = createListWithItemsAndCallbacks ( ) ;
448
+ Dragstart . on ( src ) . dragover ( target , { ctrlKey : true } ) . drop ( target ) ;
449
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'copy' ) ;
450
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'copy' ) ;
451
+ } ) ;
452
+
453
+ it ( 'is link if Alt key is pressed' , function ( ) {
454
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="all"></div>' ) ;
455
+ var target = createListWithItemsAndCallbacks ( ) ;
456
+ Dragstart . on ( src ) . dragover ( target , { altKey : true } ) . drop ( target ) ;
457
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'link' ) ;
458
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'link' ) ;
459
+ } ) ;
460
+
461
+ it ( 'ignores Ctrl key if copy is not possible' , function ( ) {
462
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="linkMove"></div>' ) ;
463
+ var target = createListWithItemsAndCallbacks ( ) ;
464
+ Dragstart . on ( src ) . dragover ( target , { ctrlKey : true } ) . drop ( target ) ;
465
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'move' ) ;
466
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'move' ) ;
467
+ } ) ;
468
+
469
+ it ( 'respects effectAllowed from external drops' , function ( ) {
470
+ var target = createListWithItemsAndCallbacks ( ) ;
471
+ Dragenter . validExternalOn ( target , { effectAllowed : 'copyLink' } ) . dragover ( target ) . drop ( target ) ;
472
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'copy' ) ;
473
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'copy' ) ;
474
+ } ) ;
475
+
476
+ it ( 'respects effectAllowed from external drops even in IE' , function ( ) {
477
+ var target = createListWithItemsAndCallbacks ( ) ;
478
+ Dragenter . externalOn ( target , { 'Text' : '{}' } , { effectAllowed : 'copyLink' } )
479
+ . dragover ( target ) . drop ( target ) ;
480
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'copy' ) ;
481
+ expect ( target . scope ( ) . drop . dropEffect ) . toBe ( 'copy' ) ;
482
+ } ) ;
483
+
484
+ it ( 'ignores effectAllowed from internal drops in IE' , function ( ) {
485
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="copyLink"></div>' ) ;
486
+ var target = createListWithItemsAndCallbacks ( ) ;
487
+ Dragstart . on ( src , { allowedMimeTypes : [ 'Text' ] } ) . dragover ( target , { altKey : true } ) ;
488
+ expect ( target . scope ( ) . dragover . dropEffect ) . toBe ( 'link' ) ;
489
+ } ) ;
490
+
491
+ it ( 'does not set dropEffect in IE' , function ( ) {
492
+ var src = compileAndLink ( '<div dnd-draggable="{}" dnd-effect-allowed="copyLink"></div>' ) ;
493
+ var target = createListWithItemsAndCallbacks ( ) ;
494
+ var dragover = Dragstart . on ( src , { allowedMimeTypes : [ 'Text' ] } ) . dragover ( target ) ;
495
+ expect ( dragover . dropEffect ) . toBeUndefined ( ) ;
496
+ } ) ;
497
+ } ) ;
498
+
402
499
function verifyDropAccepted ( result ) {
403
500
expect ( result . defaultPrevented ) . toBe ( true ) ;
404
501
if ( result . type == 'dragenter' ) {
@@ -414,6 +511,7 @@ describe('dndList', function() {
414
511
expect ( result . returnValue ) . toBe ( true ) ;
415
512
expect ( result . propagationStopped ) . toBe ( false ) ;
416
513
expect ( result . defaultPrevented ) . toBe ( opt_defaultPrevented || false ) ;
514
+ expect ( result . dropEffect ) . toBeUndefined ( ) ;
417
515
expect ( element . hasClass ( "dndDragover" ) ) . toBe ( false ) ;
418
516
expect ( element . children ( ) . length ) . toBe ( opt_children || 0 ) ;
419
517
}
@@ -428,10 +526,12 @@ describe('dndList', function() {
428
526
verify ( drop , element ) ;
429
527
}
430
528
431
- function createListWithItemsAndCallbacks ( horizontal ) {
432
- var params = '{event: event, index: index, item: item, external: external, type: type}' ;
529
+ function createListWithItemsAndCallbacks ( horizontal , effectAllowed ) {
530
+ var params = '{event: event, dropEffect: dropEffect, index: index, '
531
+ + 'item: item, external: external, type: type}' ;
433
532
var element = compileAndLink ( '<ul dnd-list="list" dnd-external-sources="true" ' +
434
533
'dnd-horizontal-list="' + ( horizontal || 'false' ) + '" ' +
534
+ ( effectAllowed ? 'dnd-effect-allowed="' + effectAllowed + '" ' : '' ) +
435
535
'dnd-dragover="dragover = ' + params + '" ' +
436
536
'dnd-drop="dropHandler(' + params + ')" ' +
437
537
'dnd-inserted="inserted = ' + params + '">' +
0 commit comments