diff --git a/src/cdk-experimental/drag-drop/drag-drop-registry.spec.ts b/src/cdk-experimental/drag-drop/drag-drop-registry.spec.ts index 6a6918baa4f..5acc567d30c 100644 --- a/src/cdk-experimental/drag-drop/drag-drop-registry.spec.ts +++ b/src/cdk-experimental/drag-drop/drag-drop-registry.spec.ts @@ -6,7 +6,7 @@ import { createTouchEvent, dispatchTouchEvent, } from '@angular/cdk/testing'; -import {CdkDragDropRegistry} from './drag-drop-registry'; +import {DragDropRegistry} from './drag-drop-registry'; import {DragDropModule} from './drag-drop-module'; import {CdkDrag} from './drag'; import {CdkDrop} from './drop'; @@ -14,7 +14,7 @@ import {CdkDrop} from './drop'; describe('DragDropRegistry', () => { let fixture: ComponentFixture; let testComponent: SimpleDropZone; - let registry: CdkDragDropRegistry; + let registry: DragDropRegistry; beforeEach(fakeAsync(() => { TestBed.configureTestingModule({ @@ -26,7 +26,7 @@ describe('DragDropRegistry', () => { testComponent = fixture.componentInstance; fixture.detectChanges(); - inject([CdkDragDropRegistry], (c: CdkDragDropRegistry) => { + inject([DragDropRegistry], (c: DragDropRegistry) => { registry = c; })(); })); @@ -59,7 +59,7 @@ describe('DragDropRegistry', () => { registry.startDragging(firstItem, createMouseEvent('mousedown')); expect(registry.isDragging(firstItem)).toBe(true); - registry.remove(firstItem); + registry.removeDragItem(firstItem); expect(registry.isDragging(firstItem)).toBe(false); }); @@ -130,7 +130,7 @@ describe('DragDropRegistry', () => { }); it('should not throw when trying to register the same container again', () => { - expect(() => registry.register(testComponent.dropInstances.first)).not.toThrow(); + expect(() => registry.registerDropContainer(testComponent.dropInstances.first)).not.toThrow(); }); it('should throw when trying to register a different container with the same id', () => { diff --git a/src/cdk-experimental/drag-drop/drag-drop-registry.ts b/src/cdk-experimental/drag-drop/drag-drop-registry.ts index 147c457f2cb..2e7604e23eb 100644 --- a/src/cdk-experimental/drag-drop/drag-drop-registry.ts +++ b/src/cdk-experimental/drag-drop/drag-drop-registry.ts @@ -10,8 +10,6 @@ import {Injectable, NgZone, OnDestroy, Inject} from '@angular/core'; import {DOCUMENT} from '@angular/common'; import {supportsPassiveEventListeners} from '@angular/cdk/platform'; import {Subject} from 'rxjs'; -import {CdkDrop} from './drop'; -import {CdkDrag} from './drag'; /** Event options that can be used to bind an active event. */ const activeEventOptions = supportsPassiveEventListeners() ? {passive: false} : false; @@ -20,35 +18,38 @@ const activeEventOptions = supportsPassiveEventListeners() ? {passive: false} : type PointerEventHandler = (event: TouchEvent | MouseEvent) => void; /** - * Service that keeps track of all the `CdkDrag` and `CdkDrop` instances, and - * manages global event listeners on the `document`. + * Service that keeps track of all the drag item and drop container + * instances, and manages global event listeners on the `document`. * @docs-private */ +// Note: this class is generic, rather than referencing CdkDrag and CdkDrop directly, in order to +// avoid circular imports. If we were to reference them here, importing the registry into the +// classes that are registering themselves will introduce a circular import. @Injectable({providedIn: 'root'}) -export class CdkDragDropRegistry implements OnDestroy { +export class DragDropRegistry implements OnDestroy { private _document: Document; - /** Registered `CdkDrop` instances. */ - private _dropInstances = new Set(); + /** Registered drop container instances. */ + private _dropInstances = new Set(); - /** Registered `CdkDrag` instances. */ - private _dragInstances = new Set(); + /** Registered drag item instances. */ + private _dragInstances = new Set(); - /** `CdkDrag` instances that are currently being dragged. */ - private _activeDragInstances = new Set(); + /** Drag item instances that are currently being dragged. */ + private _activeDragInstances = new Set(); /** Keeps track of the event listeners that we've bound to the `document`. */ private _globalListeners = new Map(); /** * Emits the `touchmove` or `mousemove` events that are dispatched - * while the user is dragging a `CdkDrag` instance. + * while the user is dragging a drag item instance. */ readonly pointerMove: Subject = new Subject(); /** * Emits the `touchend` or `mouseup` events that are dispatched - * while the user is dragging a `CdkDrag` instance. + * while the user is dragging a drag item instance. */ readonly pointerUp: Subject = new Subject(); @@ -58,52 +59,44 @@ export class CdkDragDropRegistry implements OnDestroy { this._document = _document; } - /** Adds a `CdkDrop` instance to the registry. */ - register(drop: CdkDrop); - - /** Adds a `CdkDrag` instance to the registry. */ - register(drag: CdkDrag); - - register(instance: CdkDrop | CdkDrag) { - if (instance instanceof CdkDrop) { - if (!this._dropInstances.has(instance)) { - if (this.getDropContainer(instance.id)) { - throw Error(`Drop instance with id "${instance.id}" has already been registered.`); - } - - this._dropInstances.add(instance); + /** Adds a drop container to the registry. */ + registerDropContainer(drop: C) { + if (!this._dropInstances.has(drop)) { + if (this.getDropContainer(drop.id)) { + throw Error(`Drop instance with id "${drop.id}" has already been registered.`); } - } else { - this._dragInstances.add(instance); - if (this._dragInstances.size === 1) { - this._ngZone.runOutsideAngular(() => { - // The event handler has to be explicitly active, because - // newer browsers make it passive by default. - this._document.addEventListener('touchmove', this._preventScrollListener, - activeEventOptions); - }); - } + this._dropInstances.add(drop); } } - /** Removes a `CdkDrop` instance from the registry. */ - remove(drop: CdkDrop); + /** Adds a drag item instance to the registry. */ + registerDragItem(drag: I) { + this._dragInstances.add(drag); - /** Removes a `CdkDrag` instance from the registry. */ - remove(drag: CdkDrag); + if (this._dragInstances.size === 1) { + this._ngZone.runOutsideAngular(() => { + // The event handler has to be explicitly active, because + // newer browsers make it passive by default. + this._document.addEventListener('touchmove', this._preventScrollListener, + activeEventOptions); + }); + } + } - remove(instance: CdkDrop | CdkDrag) { - if (instance instanceof CdkDrop) { - this._dropInstances.delete(instance); - } else { - this._dragInstances.delete(instance); - this.stopDragging(instance); + /** Removes a drop container from the registry. */ + removeDropContainer(drop: C) { + this._dropInstances.delete(drop); + } - if (this._dragInstances.size === 0) { - this._document.removeEventListener('touchmove', this._preventScrollListener, - activeEventOptions as any); - } + /** Removes a drag item instance from the registry. */ + removeDragItem(drag: I) { + this._dragInstances.delete(drag); + this.stopDragging(drag); + + if (this._dragInstances.size === 0) { + this._document.removeEventListener('touchmove', this._preventScrollListener, + activeEventOptions as any); } } @@ -112,7 +105,7 @@ export class CdkDragDropRegistry implements OnDestroy { * @param drag Drag instance which is being dragged. * @param event Event that initiated the dragging. */ - startDragging(drag: CdkDrag, event: TouchEvent | MouseEvent) { + startDragging(drag: I, event: TouchEvent | MouseEvent) { this._activeDragInstances.add(drag); if (this._activeDragInstances.size === 1) { @@ -134,8 +127,8 @@ export class CdkDragDropRegistry implements OnDestroy { } } - /** Stops dragging a `CdkDrag` instance. */ - stopDragging(drag: CdkDrag) { + /** Stops dragging a drag item instance. */ + stopDragging(drag: I) { this._activeDragInstances.delete(drag); if (this._activeDragInstances.size === 0) { @@ -143,19 +136,19 @@ export class CdkDragDropRegistry implements OnDestroy { } } - /** Gets whether a `CdkDrag` instance is currently being dragged. */ - isDragging(drag: CdkDrag) { + /** Gets whether a drag item instance is currently being dragged. */ + isDragging(drag: I) { return this._activeDragInstances.has(drag); } - /** Gets a `CdkDrop` instance by its id. */ - getDropContainer(id: string): CdkDrop | undefined { + /** Gets a drop container by its id. */ + getDropContainer(id: string): C | undefined { return Array.from(this._dropInstances).find(instance => instance.id === id); } ngOnDestroy() { - this._dragInstances.forEach(instance => this.remove(instance)); - this._dropInstances.forEach(instance => this.remove(instance)); + this._dragInstances.forEach(instance => this.removeDragItem(instance)); + this._dropInstances.forEach(instance => this.removeDropContainer(instance)); this._clearGlobalListeners(); this.pointerMove.complete(); this.pointerUp.complete(); diff --git a/src/cdk-experimental/drag-drop/drag.ts b/src/cdk-experimental/drag-drop/drag.ts index e0f099ba0a5..0034438b3cb 100644 --- a/src/cdk-experimental/drag-drop/drag.ts +++ b/src/cdk-experimental/drag-drop/drag.ts @@ -31,7 +31,7 @@ import {CdkDragStart, CdkDragEnd, CdkDragExit, CdkDragEnter, CdkDragDrop} from ' import {CdkDragPreview} from './drag-preview'; import {CdkDragPlaceholder} from './drag-placeholder'; import {ViewportRuler} from '@angular/cdk/overlay'; -import {CdkDragDropRegistry} from './drag-drop-registry'; +import {DragDropRegistry} from './drag-drop-registry'; import {Subject, merge} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; @@ -138,10 +138,10 @@ export class CdkDrag implements OnDestroy { private _ngZone: NgZone, private _viewContainerRef: ViewContainerRef, private _viewportRuler: ViewportRuler, - private _dragDropRegistry: CdkDragDropRegistry, + private _dragDropRegistry: DragDropRegistry, CdkDropContainer>, @Optional() private _dir: Directionality) { this._document = document; - _dragDropRegistry.register(this); + _dragDropRegistry.registerDragItem(this); } /** @@ -165,7 +165,7 @@ export class CdkDrag implements OnDestroy { } this._nextSibling = null; - this._dragDropRegistry.remove(this); + this._dragDropRegistry.removeDragItem(this); this._destroyed.next(); this._destroyed.complete(); } diff --git a/src/cdk-experimental/drag-drop/drop-container.ts b/src/cdk-experimental/drag-drop/drop-container.ts index 016792f2b16..36bd6f49df5 100644 --- a/src/cdk-experimental/drag-drop/drop-container.ts +++ b/src/cdk-experimental/drag-drop/drop-container.ts @@ -13,6 +13,9 @@ export interface CdkDropContainer { /** Arbitrary data to attach to all events emitted by this container. */ data: T; + /** Unique ID for the drop zone. */ + id: string; + /** Direction in which the list is oriented. */ orientation: 'horizontal' | 'vertical'; diff --git a/src/cdk-experimental/drag-drop/drop.ts b/src/cdk-experimental/drag-drop/drop.ts index 95e59c71f5a..f055d3a44da 100644 --- a/src/cdk-experimental/drag-drop/drop.ts +++ b/src/cdk-experimental/drag-drop/drop.ts @@ -23,7 +23,7 @@ import { import {CdkDrag} from './drag'; import {CdkDragExit, CdkDragEnter, CdkDragDrop} from './drag-events'; import {CDK_DROP_CONTAINER} from './drop-container'; -import {CdkDragDropRegistry} from './drag-drop-registry'; +import {DragDropRegistry} from './drag-drop-registry'; /** Counter used to generate unique ids for drop zones. */ let _uniqueIdCounter = 0; @@ -85,14 +85,14 @@ export class CdkDrop implements OnInit, OnDestroy { constructor( public element: ElementRef, - private _dragDropRegistry: CdkDragDropRegistry) {} + private _dragDropRegistry: DragDropRegistry>) {} ngOnInit() { - this._dragDropRegistry.register(this); + this._dragDropRegistry.registerDropContainer(this); } ngOnDestroy() { - this._dragDropRegistry.remove(this); + this._dragDropRegistry.removeDropContainer(this); } /** Whether an item in the container is being dragged. */