Skip to content

refactor(drag-drop): expose more private apis as protected #14134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 32 additions & 32 deletions src/cdk/drag-drop/drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
rootElement.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
this._handles.changes.pipe(startWith(null)).subscribe(() =>
toggleNativeDragInteractions(rootElement, this.getChildHandles().length > 0));
toggleNativeDragInteractions(rootElement, this._getChildHandles().length > 0));
});
}

Expand All @@ -349,7 +349,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
if (this._isDragging()) {
// Since we move out the element to the end of the body while it's being
// dragged, we have to make sure that it's removed if it gets destroyed.
this._removeElement(this._rootElement);
removeElement(this._rootElement);
}
}

Expand All @@ -368,13 +368,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
}

/** Gets only handles that are not inside descendant `CdkDrag` instances. */
private getChildHandles() {
protected _getChildHandles() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might be inconsistent about this, but the coding standards doc says no prefix for protected

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing a quick code search shows that most of the protected APIs we have at the moment are underscored.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, let's revisit this another time

return this._handles.filter(handle => handle._parentDrag === this);
}

/** Handler for the `mousedown`/`touchstart` events. */
_pointerDown = (event: MouseEvent | TouchEvent) => {
const handles = this.getChildHandles();
const handles = this._getChildHandles();

// Delegate the event based on whether it started from a handle or the element itself.
if (handles.length) {
Expand All @@ -398,16 +398,16 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
* @param referenceElement Element that started the drag sequence.
* @param event Browser event object that started the sequence.
*/
private _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
protected _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
// Always stop propagation for the event that initializes
// the dragging sequence, in order to prevent it from potentially
// starting another sequence for a draggable parent somewhere up the DOM tree.
event.stopPropagation();

const isDragging = this._isDragging();
const isTouchEvent = this._isTouchEvent(event);
const isAuxiliaryMouseButton = !isTouchEvent && (event as MouseEvent).button !== 0;
const isSyntheticEvent = !isTouchEvent && this._lastTouchEventTime &&
const wasTouchEvent = isTouchEvent(event);
const isAuxiliaryMouseButton = !wasTouchEvent && (event as MouseEvent).button !== 0;
const isSyntheticEvent = !wasTouchEvent && this._lastTouchEventTime &&
this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();

// If the event started from an element with the native HTML drag&drop, it'll interfere
Expand Down Expand Up @@ -453,11 +453,11 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
}

/** Starts the dragging sequence. */
private _startDragSequence(event: MouseEvent | TouchEvent) {
protected _startDragSequence(event: MouseEvent | TouchEvent) {
// Emit the event on the item before the one on the container.
this.started.emit({source: this});

if (this._isTouchEvent(event)) {
if (isTouchEvent(event)) {
this._lastTouchEventTime = Date.now();
}

Expand All @@ -482,7 +482,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
}

/** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
private _pointerMove = (event: MouseEvent | TouchEvent) => {
protected _pointerMove = (event: MouseEvent | TouchEvent) => {
if (!this._hasStartedDragging) {
const pointerPosition = this._getPointerPositionOnPage(event);
const distanceX = Math.abs(pointerPosition.x - this._pickupPositionOnPage.x);
Expand Down Expand Up @@ -551,7 +551,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
}

/** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
private _pointerUp = (event: MouseEvent | TouchEvent) => {
protected _pointerUp = (event: MouseEvent | TouchEvent) => {
if (!this._isDragging()) {
return;
}
Expand Down Expand Up @@ -721,7 +721,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
const elementRect = this._rootElement.getBoundingClientRect();
const handleElement = referenceElement === this._rootElement ? null : referenceElement;
const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
const point = this._isTouchEvent(event) ? event.targetTouches[0] : event;
const point = isTouchEvent(event) ? event.targetTouches[0] : event;
const x = point.pageX - referenceRect.left - this._scrollPosition.left;
const y = point.pageY - referenceRect.top - this._scrollPosition.top;

Expand Down Expand Up @@ -778,20 +778,10 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
});
}

/**
* Helper to remove an element from the DOM and to do all the necessary null checks.
* @param element Element to be removed.
*/
private _removeElement(element: HTMLElement | null) {
if (element && element.parentNode) {
element.parentNode.removeChild(element);
}
}

/** Determines the point of the page that was touched by the user. */
private _getPointerPositionOnPage(event: MouseEvent | TouchEvent): Point {
// `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
const point = this._isTouchEvent(event) ? (event.touches[0] || event.changedTouches[0]) : event;
const point = isTouchEvent(event) ? (event.touches[0] || event.changedTouches[0]) : event;

return {
x: point.pageX - this._scrollPosition.left,
Expand Down Expand Up @@ -826,15 +816,10 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
return point;
}

/** Determines whether an event is a touch event. */
private _isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
return event.type.startsWith('touch');
}

/** Destroys the preview element and its ViewRef. */
private _destroyPreview() {
if (this._preview) {
this._removeElement(this._preview);
removeElement(this._preview);
}

if (this._previewRef) {
Expand All @@ -847,7 +832,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
/** Destroys the placeholder element and its ViewRef. */
private _destroyPlaceholder() {
if (this._placeholder) {
this._removeElement(this._placeholder);
removeElement(this._placeholder);
}

if (this._placeholderRef) {
Expand Down Expand Up @@ -885,7 +870,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
}

/** Gets the root draggable element, based on the `rootElementSelector`. */
private _getRootElement(): HTMLElement {
protected _getRootElement(): HTMLElement {
const element = this.element.nativeElement;
const rootElement = this.rootElementSelector ?
getClosestMatchingAncestor(element, this.rootElementSelector) : null;
Expand Down Expand Up @@ -950,3 +935,18 @@ function getClosestMatchingAncestor(element: HTMLElement, selector: string) {
currentElement = currentElement.parentElement;
}
}

/**
* Helper to remove an element from the DOM and to do all the necessary null checks.
* @param element Element to be removed.
*/
function removeElement(element: HTMLElement | null) {
if (element && element.parentNode) {
element.parentNode.removeChild(element);
}
}

/** Determines whether an event is a touch event. */
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
return event.type.startsWith('touch');
}
48 changes: 24 additions & 24 deletions src/cdk/drag-drop/drop-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,14 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
_dragging = false;

/** Cache of the dimensions of all the items and the sibling containers. */
private _positionCache: PositionCache = {items: [], siblings: [], self: {} as ClientRect};
protected _positionCache: PositionCache = {items: [], siblings: [], self: {} as ClientRect};

/**
* Draggable items that are currently active inside the container. Includes the items
* from `_draggables`, as well as any items that have been dragged in, but haven't
* been dropped yet.
*/
private _activeDraggables: CdkDrag[];
protected _activeDraggables: CdkDrag[];

/**
* Keeps track of the item that was last swapped with the dragged item, as
Expand Down Expand Up @@ -382,10 +382,10 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
// Round the transforms since some browsers will
// blur the elements, for sub-pixel transforms.
elementToOffset.style.transform = `translate3d(${Math.round(sibling.offset)}px, 0, 0)`;
this._adjustClientRect(sibling.clientRect, 0, offset);
adjustClientRect(sibling.clientRect, 0, offset);
} else {
elementToOffset.style.transform = `translate3d(0, ${Math.round(sibling.offset)}px, 0)`;
this._adjustClientRect(sibling.clientRect, offset, 0);
adjustClientRect(sibling.clientRect, offset, 0);
}
});
}
Expand Down Expand Up @@ -487,7 +487,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
}

/** Resets the container to its initial state. */
private _reset() {
protected _reset() {
this._dragging = false;

// TODO(crisbeto): may have to wait for the animations to finish.
Expand All @@ -499,28 +499,14 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
this._previousSwap.delta = 0;
}

/**
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
* @param clientRect `ClientRect` that should be updated.
* @param top Amount to add to the `top` position.
* @param left Amount to add to the `left` position.
*/
private _adjustClientRect(clientRect: ClientRect, top: number, left: number) {
clientRect.top += top;
clientRect.bottom = clientRect.top + clientRect.height;

clientRect.left += left;
clientRect.right = clientRect.left + clientRect.width;
}

/**
* Gets the index of an item in the drop container, based on the position of the user's pointer.
* @param item Item that is being sorted.
* @param pointerX Position of the user's pointer along the X axis.
* @param pointerY Position of the user's pointer along the Y axis.
* @param delta Direction in which the user is moving their pointer.
*/
private _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
protected _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
delta?: {x: number, y: number}) {

const isHorizontal = this.orientation === 'horizontal';
Expand Down Expand Up @@ -555,7 +541,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
* @param pointerX Coordinates along the X axis.
* @param pointerY Coordinates along the Y axis.
*/
private _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
protected _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
const {top, right, bottom, left, width, height} = this._positionCache.self;
const xThreshold = width * DROP_PROXIMITY_THRESHOLD;
const yThreshold = height * DROP_PROXIMITY_THRESHOLD;
Expand All @@ -570,7 +556,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
* @param newPosition Position of the item where the current item should be moved.
* @param delta Direction in which the user is moving.
*/
private _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
protected _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
const isHorizontal = this.orientation === 'horizontal';
let itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
newPosition.top - currentPosition.top;
Expand All @@ -590,7 +576,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
* @param siblings All of the items in the list.
* @param delta Direction in which the user is moving.
*/
private _getSiblingOffsetPx(currentIndex: number,
protected _getSiblingOffsetPx(currentIndex: number,
siblings: ItemPositionCacheEntry[],
delta: 1 | -1) {

Expand Down Expand Up @@ -618,7 +604,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
}

/** Gets an array of unique drop lists that the current list is connected to. */
private _getConnectedLists(): CdkDropList[] {
protected _getConnectedLists(): CdkDropList[] {
const siblings = coerceArray(this.connectedTo).map(drop => {
return typeof drop === 'string' ? this._dragDropRegistry.getDropContainer(drop)! : drop;
});
Expand Down Expand Up @@ -665,3 +651,17 @@ function isInsideClientRect(clientRect: ClientRect, x: number, y: number) {
const {top, bottom, left, right} = clientRect;
return y >= top && y <= bottom && x >= left && x <= right;
}

/**
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
* @param clientRect `ClientRect` that should be updated.
* @param top Amount to add to the `top` position.
* @param left Amount to add to the `left` position.
*/
function adjustClientRect(clientRect: ClientRect, top: number, left: number) {
clientRect.top += top;
clientRect.bottom = clientRect.top + clientRect.height;

clientRect.left += left;
clientRect.right = clientRect.left + clientRect.width;
}
1 change: 1 addition & 0 deletions src/cdk/drag-drop/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './drag-preview';
export * from './drag-placeholder';
export * from './drag-drop-module';
export * from './drag-drop-registry';
export * from './drag-parent';
19 changes: 19 additions & 0 deletions tools/public_api_guard/cdk/drag-drop.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ export declare const CDK_DRAG_CONFIG: InjectionToken<CdkDragConfig>;

export declare function CDK_DRAG_CONFIG_FACTORY(): CdkDragConfig;

export declare const CDK_DRAG_PARENT: InjectionToken<{}>;

export declare const CDK_DROP_LIST_CONTAINER: InjectionToken<CdkDropListContainer<any>>;

export declare class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
_handles: QueryList<CdkDragHandle>;
_hasStartedDragging: boolean;
_placeholderTemplate: CdkDragPlaceholder;
_pointerDown: (event: TouchEvent | MouseEvent) => void;
protected _pointerMove: (event: TouchEvent | MouseEvent) => void;
protected _pointerUp: (event: TouchEvent | MouseEvent) => void;
_previewTemplate: CdkDragPreview;
boundaryElementSelector: string;
data: T;
Expand All @@ -26,7 +30,11 @@ export declare class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
constructor(
element: ElementRef<HTMLElement>,
dropContainer: CdkDropListContainer, document: any, _ngZone: NgZone, _viewContainerRef: ViewContainerRef, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<CdkDrag<T>, CdkDropListContainer>, _config: CdkDragConfig, _dir: Directionality);
protected _getChildHandles(): CdkDragHandle[];
protected _getRootElement(): HTMLElement;
protected _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent): void;
_isDragging(): boolean;
protected _startDragSequence(event: MouseEvent | TouchEvent): void;
getPlaceholderElement(): HTMLElement;
getRootElement(): HTMLElement;
ngAfterViewInit(): void;
Expand Down Expand Up @@ -106,8 +114,10 @@ export interface CdkDragStart<T = any> {
}

export declare class CdkDropList<T = any> implements OnInit, OnDestroy {
protected _activeDraggables: CdkDrag[];
_draggables: QueryList<CdkDrag>;
_dragging: boolean;
protected _positionCache: PositionCache;
connectedTo: (CdkDropList | string)[] | CdkDropList | string;
data: T;
disabled: boolean;
Expand All @@ -121,8 +131,17 @@ export declare class CdkDropList<T = any> implements OnInit, OnDestroy {
orientation: 'horizontal' | 'vertical';
sorted: EventEmitter<CdkDragSortEvent<T>>;
constructor(element: ElementRef<HTMLElement>, _dragDropRegistry: DragDropRegistry<CdkDrag, CdkDropList<T>>, _changeDetectorRef: ChangeDetectorRef, _dir?: Directionality | undefined, _group?: CdkDropListGroup<CdkDropList<any>> | undefined, _document?: any);
protected _getConnectedLists(): CdkDropList[];
protected _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number, delta?: {
x: number;
y: number;
}): number;
protected _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1): number;
_getSiblingContainerFromPosition(item: CdkDrag, x: number, y: number): CdkDropList | null;
protected _getSiblingOffsetPx(currentIndex: number, siblings: ItemPositionCacheEntry[], delta: 1 | -1): number;
_isOverContainer(x: number, y: number): boolean;
protected _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean;
protected _reset(): void;
_sortItem(item: CdkDrag, pointerX: number, pointerY: number, pointerDelta: {
x: number;
y: number;
Expand Down