Skip to content

Commit f229e7b

Browse files
committed
refactor(cdk/drag-drop): remove unnecessary generics (#29542)
Previously we used generics in the `DragDropRegistry` to avoid circular dependencies. Now that we can use type-only imports, we don't need the generics anymore. (cherry picked from commit 78c6941)
1 parent 8dfd1dc commit f229e7b

File tree

8 files changed

+50
-57
lines changed

8 files changed

+50
-57
lines changed

src/cdk/drag-drop/drag-drop-registry.spec.ts

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import {
99
} from '../testing/private';
1010
import {DragDropRegistry} from './drag-drop-registry';
1111
import {DragDropModule} from './drag-drop-module';
12+
import {DragRef} from './drag-ref';
1213

1314
describe('DragDropRegistry', () => {
1415
let fixture: ComponentFixture<BlankComponent>;
15-
let registry: DragDropRegistry<DragItem, DragList>;
16+
let registry: DragDropRegistry;
1617

1718
beforeEach(fakeAsync(() => {
1819
TestBed.configureTestingModule({
@@ -22,21 +23,21 @@ describe('DragDropRegistry', () => {
2223
fixture = TestBed.createComponent(BlankComponent);
2324
fixture.detectChanges();
2425

25-
inject([DragDropRegistry], (c: DragDropRegistry<DragItem, DragList>) => {
26+
inject([DragDropRegistry], (c: DragDropRegistry) => {
2627
registry = c;
2728
})();
2829
}));
2930

3031
it('should be able to start dragging an item', () => {
31-
const item = new DragItem();
32+
const item = new DragItem() as unknown as DragRef;
3233

3334
expect(registry.isDragging(item)).toBe(false);
3435
registry.startDragging(item, createMouseEvent('mousedown'));
3536
expect(registry.isDragging(item)).toBe(true);
3637
});
3738

3839
it('should be able to stop dragging an item', () => {
39-
const item = new DragItem();
40+
const item = new DragItem() as unknown as DragRef;
4041

4142
registry.startDragging(item, createMouseEvent('mousedown'));
4243
expect(registry.isDragging(item)).toBe(true);
@@ -46,7 +47,7 @@ describe('DragDropRegistry', () => {
4647
});
4748

4849
it('should stop dragging an item if it is removed', () => {
49-
const item = new DragItem();
50+
const item = new DragItem() as unknown as DragRef;
5051

5152
registry.startDragging(item, createMouseEvent('mousedown'));
5253
expect(registry.isDragging(item)).toBe(true);
@@ -58,7 +59,7 @@ describe('DragDropRegistry', () => {
5859
it('should dispatch `mousemove` events after starting to drag via the mouse', () => {
5960
const spy = jasmine.createSpy('pointerMove spy');
6061
const subscription = registry.pointerMove.subscribe(spy);
61-
const item = new DragItem(true);
62+
const item = new DragItem(true) as unknown as DragRef;
6263
registry.startDragging(item, createMouseEvent('mousedown'));
6364
dispatchMouseEvent(document, 'mousemove');
6465

@@ -70,7 +71,7 @@ describe('DragDropRegistry', () => {
7071
it('should dispatch `touchmove` events after starting to drag via touch', () => {
7172
const spy = jasmine.createSpy('pointerMove spy');
7273
const subscription = registry.pointerMove.subscribe(spy);
73-
const item = new DragItem(true);
74+
const item = new DragItem(true) as unknown as DragRef;
7475
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
7576
dispatchTouchEvent(document, 'touchmove');
7677

@@ -82,7 +83,7 @@ describe('DragDropRegistry', () => {
8283
it('should dispatch pointer move events if event propagation is stopped', () => {
8384
const spy = jasmine.createSpy('pointerMove spy');
8485
const subscription = registry.pointerMove.subscribe(spy);
85-
const item = new DragItem(true);
86+
const item = new DragItem(true) as unknown as DragRef;
8687
fixture.nativeElement.addEventListener('mousemove', (e: MouseEvent) => e.stopPropagation());
8788
registry.startDragging(item, createMouseEvent('mousedown'));
8889
dispatchMouseEvent(fixture.nativeElement, 'mousemove');
@@ -95,7 +96,7 @@ describe('DragDropRegistry', () => {
9596
it('should dispatch `mouseup` events after ending the drag via the mouse', () => {
9697
const spy = jasmine.createSpy('pointerUp spy');
9798
const subscription = registry.pointerUp.subscribe(spy);
98-
const item = new DragItem();
99+
const item = new DragItem() as unknown as DragRef;
99100

100101
registry.startDragging(item, createMouseEvent('mousedown'));
101102
dispatchMouseEvent(document, 'mouseup');
@@ -108,7 +109,7 @@ describe('DragDropRegistry', () => {
108109
it('should dispatch `touchend` events after ending the drag via touch', () => {
109110
const spy = jasmine.createSpy('pointerUp spy');
110111
const subscription = registry.pointerUp.subscribe(spy);
111-
const item = new DragItem();
112+
const item = new DragItem() as unknown as DragRef;
112113

113114
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
114115
dispatchTouchEvent(document, 'touchend');
@@ -121,7 +122,7 @@ describe('DragDropRegistry', () => {
121122
it('should dispatch pointer up events if event propagation is stopped', () => {
122123
const spy = jasmine.createSpy('pointerUp spy');
123124
const subscription = registry.pointerUp.subscribe(spy);
124-
const item = new DragItem();
125+
const item = new DragItem() as unknown as DragRef;
125126

126127
fixture.nativeElement.addEventListener('mouseup', (e: MouseEvent) => e.stopPropagation());
127128
registry.startDragging(item, createMouseEvent('mousedown'));
@@ -148,7 +149,7 @@ describe('DragDropRegistry', () => {
148149
});
149150

150151
it('should not emit pointer events when dragging is over (multi touch)', () => {
151-
const item = new DragItem();
152+
const item = new DragItem() as unknown as DragRef;
152153

153154
// First finger down
154155
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
@@ -183,7 +184,7 @@ describe('DragDropRegistry', () => {
183184
});
184185

185186
it('should prevent the default `touchmove` action when an item is being dragged', () => {
186-
const item = new DragItem(true);
187+
const item = new DragItem(true) as unknown as DragRef;
187188
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
188189
expect(dispatchTouchEvent(document, 'touchmove').defaultPrevented).toBe(true);
189190
});
@@ -192,7 +193,7 @@ describe('DragDropRegistry', () => {
192193
'should prevent the default `touchmove` if the item does not consider itself as being ' +
193194
'dragged yet',
194195
() => {
195-
const item = new DragItem(false);
196+
const item = new DragItem(false) as unknown as DragRef & DragItem;
196197
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
197198
expect(dispatchTouchEvent(document, 'touchmove').defaultPrevented).toBe(false);
198199

@@ -202,7 +203,7 @@ describe('DragDropRegistry', () => {
202203
);
203204

204205
it('should prevent the default `touchmove` if event propagation is stopped', () => {
205-
const item = new DragItem(true);
206+
const item = new DragItem(true) as unknown as DragRef;
206207
registry.startDragging(item, createTouchEvent('touchstart') as TouchEvent);
207208
fixture.nativeElement.addEventListener('touchmove', (e: TouchEvent) => e.stopPropagation());
208209

@@ -215,15 +216,15 @@ describe('DragDropRegistry', () => {
215216
});
216217

217218
it('should prevent the default `selectstart` action when an item is being dragged', () => {
218-
const item = new DragItem(true);
219+
const item = new DragItem(true) as unknown as DragRef;
219220
registry.startDragging(item, createMouseEvent('mousedown'));
220221
expect(dispatchFakeEvent(document, 'selectstart').defaultPrevented).toBe(true);
221222
});
222223

223224
it('should dispatch `scroll` events if the viewport is scrolled while dragging', () => {
224225
const spy = jasmine.createSpy('scroll spy');
225226
const subscription = registry.scrolled().subscribe(spy);
226-
const item = new DragItem();
227+
const item = new DragItem() as unknown as DragRef;
227228

228229
registry.startDragging(item, createMouseEvent('mousedown'));
229230
dispatchFakeEvent(document, 'scroll');
@@ -247,13 +248,7 @@ describe('DragDropRegistry', () => {
247248
return this.shouldBeDragging;
248249
}
249250
constructor(public shouldBeDragging = false) {
250-
registry.registerDragItem(this);
251-
}
252-
}
253-
254-
class DragList {
255-
constructor() {
256-
registry.registerDropContainer(this);
251+
registry.registerDragItem(this as unknown as DragRef);
257252
}
258253
}
259254

src/cdk/drag-drop/drag-drop-registry.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {
2424
signal,
2525
} from '@angular/core';
2626
import {Observable, Observer, Subject, merge} from 'rxjs';
27+
import type {DropListRef} from './drop-list-ref';
28+
import type {DragRef} from './drag-ref';
2729

2830
/** Event options that can be used to bind an active, capturing event. */
2931
const activeCapturingEventOptions = normalizePassiveListenerOptions({
@@ -48,28 +50,26 @@ const activeApps = new Set<ApplicationRef>();
4850
})
4951
export class _ResetsLoader {}
5052

53+
// TODO(crisbeto): remove generics when making breaking changes.
5154
/**
5255
* Service that keeps track of all the drag item and drop container
5356
* instances, and manages global event listeners on the `document`.
5457
* @docs-private
5558
*/
56-
// Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order
57-
// to avoid circular imports. If we were to reference them here, importing the registry into the
58-
// classes that are registering themselves will introduce a circular import.
5959
@Injectable({providedIn: 'root'})
60-
export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements OnDestroy {
60+
export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
6161
private _document: Document;
6262
private _appRef = inject(ApplicationRef);
6363
private _environmentInjector = inject(EnvironmentInjector);
6464

6565
/** Registered drop container instances. */
66-
private _dropInstances = new Set<C>();
66+
private _dropInstances = new Set<DropListRef>();
6767

6868
/** Registered drag item instances. */
69-
private _dragInstances = new Set<I>();
69+
private _dragInstances = new Set<DragRef>();
7070

7171
/** Drag item instances that are currently being dragged. */
72-
private _activeDragInstances: WritableSignal<I[]> = signal([]);
72+
private _activeDragInstances: WritableSignal<DragRef[]> = signal([]);
7373

7474
/** Keeps track of the event listeners that we've bound to the `document`. */
7575
private _globalListeners = new Map<
@@ -84,7 +84,7 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
8484
* Predicate function to check if an item is being dragged. Moved out into a property,
8585
* because it'll be called a lot and we don't want to create a new function every time.
8686
*/
87-
private _draggingPredicate = (item: I) => item.isDragging();
87+
private _draggingPredicate = (item: DragRef) => item.isDragging();
8888

8989
/**
9090
* Emits the `touchmove` or `mousemove` events that are dispatched
@@ -113,14 +113,14 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
113113
}
114114

115115
/** Adds a drop container to the registry. */
116-
registerDropContainer(drop: C) {
116+
registerDropContainer(drop: DropListRef) {
117117
if (!this._dropInstances.has(drop)) {
118118
this._dropInstances.add(drop);
119119
}
120120
}
121121

122122
/** Adds a drag item instance to the registry. */
123-
registerDragItem(drag: I) {
123+
registerDragItem(drag: DragRef) {
124124
this._dragInstances.add(drag);
125125

126126
// The `touchmove` event gets bound once, ahead of time, because WebKit
@@ -140,12 +140,12 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
140140
}
141141

142142
/** Removes a drop container from the registry. */
143-
removeDropContainer(drop: C) {
143+
removeDropContainer(drop: DropListRef) {
144144
this._dropInstances.delete(drop);
145145
}
146146

147147
/** Removes a drag item instance from the registry. */
148-
removeDragItem(drag: I) {
148+
removeDragItem(drag: DragRef) {
149149
this._dragInstances.delete(drag);
150150
this.stopDragging(drag);
151151

@@ -163,7 +163,7 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
163163
* @param drag Drag instance which is being dragged.
164164
* @param event Event that initiated the dragging.
165165
*/
166-
startDragging(drag: I, event: TouchEvent | MouseEvent) {
166+
startDragging(drag: DragRef, event: TouchEvent | MouseEvent) {
167167
// Do not process the same drag twice to avoid memory leaks and redundant listeners
168168
if (this._activeDragInstances().indexOf(drag) > -1) {
169169
return;
@@ -216,7 +216,7 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
216216
}
217217

218218
/** Stops dragging a drag item instance. */
219-
stopDragging(drag: I) {
219+
stopDragging(drag: DragRef) {
220220
this._activeDragInstances.update(instances => {
221221
const index = instances.indexOf(drag);
222222
if (index > -1) {
@@ -232,7 +232,7 @@ export class DragDropRegistry<I extends {isDragging(): boolean}, C> implements O
232232
}
233233

234234
/** Gets whether a drag item instance is currently being dragged. */
235-
isDragging(drag: I) {
235+
isDragging(drag: DragRef) {
236236
return this._activeDragInstances().indexOf(drag) > -1;
237237
}
238238

src/cdk/drag-drop/drag-drop.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class DragDrop {
2828
@Inject(DOCUMENT) private _document: any,
2929
private _ngZone: NgZone,
3030
private _viewportRuler: ViewportRuler,
31-
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
31+
private _dragDropRegistry: DragDropRegistry,
3232
) {}
3333

3434
/**

src/cdk/drag-drop/drag-ref.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export class DragRef<T = any> {
371371
private _document: Document,
372372
private _ngZone: NgZone,
373373
private _viewportRuler: ViewportRuler,
374-
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
374+
private _dragDropRegistry: DragDropRegistry,
375375
) {
376376
this.withRootElement(element).withParent(_config.parentDragRef || null);
377377
this._parentPositions = new ParentPositionTracker(_document);

src/cdk/drag-drop/drop-list-ref.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export class DropListRef<T = any> {
190190

191191
constructor(
192192
element: ElementRef<HTMLElement> | HTMLElement,
193-
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
193+
private _dragDropRegistry: DragDropRegistry,
194194
_document: any,
195195
private _ngZone: NgZone,
196196
private _viewportRuler: ViewportRuler,

src/cdk/drag-drop/sorting/mixed-sort-strategy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class MixedSortStrategy implements DropListSortStrategy {
5454

5555
constructor(
5656
private _document: Document,
57-
private _dragDropRegistry: DragDropRegistry<DragRef, unknown>,
57+
private _dragDropRegistry: DragDropRegistry,
5858
) {}
5959

6060
/**

src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class SingleAxisSortStrategy implements DropListSortStrategy {
5757
/** Layout direction of the drop list. */
5858
direction: Direction;
5959

60-
constructor(private _dragDropRegistry: DragDropRegistry<DragRef, unknown>) {}
60+
constructor(private _dragDropRegistry: DragDropRegistry) {}
6161

6262
/**
6363
* Keeps track of the item that was last swapped with the dragged item, as well as what direction

tools/public_api_guard/cdk/drag-drop.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ export type DragConstrainPosition = (point: Point, dragRef: DragRef) => Point;
302302

303303
// @public
304304
export class DragDrop {
305-
constructor(_document: any, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
305+
constructor(_document: any, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry);
306306
createDrag<T = any>(element: ElementRef<HTMLElement> | HTMLElement, config?: DragRefConfig): DragRef<T>;
307307
createDropList<T = any>(element: ElementRef<HTMLElement> | HTMLElement): DropListRef<T>;
308308
// (undocumented)
@@ -350,24 +350,22 @@ export class DragDropModule {
350350
}
351351

352352
// @public
353-
export class DragDropRegistry<I extends {
354-
isDragging(): boolean;
355-
}, C> implements OnDestroy {
353+
export class DragDropRegistry<_ = unknown, __ = unknown> implements OnDestroy {
356354
constructor(_ngZone: NgZone, _document: any);
357-
isDragging(drag: I): boolean;
355+
isDragging(drag: DragRef): boolean;
358356
// (undocumented)
359357
ngOnDestroy(): void;
360358
readonly pointerMove: Subject<TouchEvent | MouseEvent>;
361359
readonly pointerUp: Subject<TouchEvent | MouseEvent>;
362-
registerDragItem(drag: I): void;
363-
registerDropContainer(drop: C): void;
364-
removeDragItem(drag: I): void;
365-
removeDropContainer(drop: C): void;
360+
registerDragItem(drag: DragRef): void;
361+
registerDropContainer(drop: DropListRef): void;
362+
removeDragItem(drag: DragRef): void;
363+
removeDropContainer(drop: DropListRef): void;
366364
// @deprecated
367365
readonly scroll: Subject<Event>;
368366
scrolled(shadowRoot?: DocumentOrShadowRoot | null): Observable<Event>;
369-
startDragging(drag: I, event: TouchEvent | MouseEvent): void;
370-
stopDragging(drag: I): void;
367+
startDragging(drag: DragRef, event: TouchEvent | MouseEvent): void;
368+
stopDragging(drag: DragRef): void;
371369
// (undocumented)
372370
static ɵfac: i0.ɵɵFactoryDeclaration<DragDropRegistry<any, any>, never>;
373371
// (undocumented)
@@ -376,7 +374,7 @@ export class DragDropRegistry<I extends {
376374

377375
// @public
378376
export class DragRef<T = any> {
379-
constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
377+
constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry);
380378
readonly beforeStarted: Subject<void>;
381379
constrainPosition?: (userPointerPosition: Point, dragRef: DragRef, dimensions: DOMRect, pickupPositionInElement: Point) => Point;
382380
data: T;
@@ -476,7 +474,7 @@ export type DropListOrientation = 'horizontal' | 'vertical' | 'mixed';
476474

477475
// @public
478476
export class DropListRef<T = any> {
479-
constructor(element: ElementRef<HTMLElement> | HTMLElement, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, _document: any, _ngZone: NgZone, _viewportRuler: ViewportRuler);
477+
constructor(element: ElementRef<HTMLElement> | HTMLElement, _dragDropRegistry: DragDropRegistry, _document: any, _ngZone: NgZone, _viewportRuler: ViewportRuler);
480478
autoScrollDisabled: boolean;
481479
autoScrollStep: number;
482480
readonly beforeStarted: Subject<void>;

0 commit comments

Comments
 (0)