diff --git a/src/cdk-experimental/drag-drop/drag.spec.ts b/src/cdk-experimental/drag-drop/drag.spec.ts index 35b56ed5da8..46258f080f5 100644 --- a/src/cdk-experimental/drag-drop/drag.spec.ts +++ b/src/cdk-experimental/drag-drop/drag.spec.ts @@ -12,7 +12,12 @@ import { } from '@angular/core'; import {TestBed, ComponentFixture, fakeAsync, flush, tick} from '@angular/core/testing'; import {DragDropModule} from './drag-drop-module'; -import {dispatchMouseEvent, dispatchTouchEvent} from '@angular/cdk/testing'; +import { + createMouseEvent, + dispatchEvent, + dispatchMouseEvent, + dispatchTouchEvent, +} from '@angular/cdk/testing'; import {Directionality} from '@angular/cdk/bidi'; import {CdkDrag} from './drag'; import {CdkDragDrop} from './drag-events'; @@ -95,6 +100,26 @@ describe('CdkDrag', () => { cleanup(); })); + + it('should not drag an element with the right mouse button', fakeAsync(() => { + const fixture = createComponent(StandaloneDraggable); + fixture.detectChanges(); + const dragElement = fixture.componentInstance.dragElement.nativeElement; + const event = createMouseEvent('mousedown', 50, 100, 2); + + expect(dragElement.style.transform).toBeFalsy(); + + dispatchEvent(dragElement, event); + fixture.detectChanges(); + + dispatchMouseEvent(document, 'mousemove', 50, 100); + fixture.detectChanges(); + + dispatchMouseEvent(document, 'mouseup'); + fixture.detectChanges(); + + expect(dragElement.style.transform).toBeFalsy(); + })); }); describe('touch dragging', () => { diff --git a/src/cdk-experimental/drag-drop/drag.ts b/src/cdk-experimental/drag-drop/drag.ts index ac4ddad852c..2682ec5f367 100644 --- a/src/cdk-experimental/drag-drop/drag.ts +++ b/src/cdk-experimental/drag-drop/drag.ts @@ -223,19 +223,23 @@ export class CdkDrag implements OnDestroy { /** Handler for when the pointer is pressed down on the element or the handle. */ private _pointerDown = (referenceElement: ElementRef, event: MouseEvent | TouchEvent) => { - if (this._dragDropRegistry.isDragging(this)) { + + const isDragging = this._dragDropRegistry.isDragging(this); + + // Abort if the user is already dragging or is using a mouse button other than the primary one. + if (isDragging || (!this._isTouchEvent(event) && event.button !== 0)) { return; } const endedOrDestroyed = merge(this.ended, this._destroyed); this._dragDropRegistry.pointerMove - .pipe(takeUntil(endedOrDestroyed)) - .subscribe(this._pointerMove); + .pipe(takeUntil(endedOrDestroyed)) + .subscribe(this._pointerMove); - this._dragDropRegistry.pointerUp - .pipe(takeUntil(endedOrDestroyed)) - .subscribe(this._pointerUp); + this._dragDropRegistry.pointerUp + .pipe(takeUntil(endedOrDestroyed)) + .subscribe(this._pointerUp); this._dragDropRegistry.startDragging(this, event); this._initialContainer = this.dropContainer; diff --git a/src/cdk/testing/event-objects.ts b/src/cdk/testing/event-objects.ts index bc235878620..96d57d0664d 100644 --- a/src/cdk/testing/event-objects.ts +++ b/src/cdk/testing/event-objects.ts @@ -7,7 +7,7 @@ */ /** Creates a browser MouseEvent with the specified options. */ -export function createMouseEvent(type: string, x = 0, y = 0) { +export function createMouseEvent(type: string, x = 0, y = 0, button = 0) { const event = document.createEvent('MouseEvent'); event.initMouseEvent(type, @@ -23,7 +23,7 @@ export function createMouseEvent(type: string, x = 0, y = 0) { false, /* altKey */ false, /* shiftKey */ false, /* metaKey */ - 0, /* button */ + button, /* button */ null /* relatedTarget */); return event;