Skip to content

fix(cdk/drag-drop): references to SVG not working inside preview #20742

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

Merged
merged 1 commit into from
Oct 16, 2020
Merged
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
14 changes: 11 additions & 3 deletions src/cdk/drag-drop/directives/drag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2035,9 +2035,14 @@ describe('CdkDrag', () => {

const preview = document.querySelector('.cdk-drag-preview')! as HTMLElement;
const previewRect = preview.getBoundingClientRect();
const zeroPxRegex = /^0(px)?$/;

expect(item.parentNode).toBe(document.body, 'Expected element to be moved out into the body');
expect(item.style.display).toBe('none', 'Expected element to be hidden');
expect(item.style.position).toBe('fixed', 'Expected element to be removed from layout');
// Use a regex here since some browsers normalize 0 to 0px, but others don't.
expect(item.style.top).toMatch(zeroPxRegex, 'Expected element to be removed from layout');
expect(item.style.left).toBe('-999em', 'Expected element to be removed from layout');
expect(item.style.opacity).toBe('0', 'Expected element to be invisible');
expect(preview).toBeTruthy('Expected preview to be in the DOM');
expect(preview.textContent!.trim())
.toContain('One', 'Expected preview content to match element');
Expand All @@ -2049,15 +2054,18 @@ describe('CdkDrag', () => {
.toBe('none', 'Expected pointer events to be disabled on the preview');
expect(preview.style.zIndex).toBe('1000', 'Expected preview to have a high default zIndex.');
// Use a regex here since some browsers normalize 0 to 0px, but others don't.
expect(preview.style.margin).toMatch(/^0(px)?$/, 'Expected the preview margin to be reset.');
expect(preview.style.margin).toMatch(zeroPxRegex, 'Expected the preview margin to be reset.');

dispatchMouseEvent(document, 'mouseup');
fixture.detectChanges();
flush();

expect(item.parentNode)
.toBe(initialParent, 'Expected element to be moved back into its old parent');
expect(item.style.display).toBeFalsy('Expected element to be visible');
expect(item.style.position).toBeFalsy('Expected element to be within the layout');
expect(item.style.top).toBeFalsy('Expected element to be within the layout');
expect(item.style.left).toBeFalsy('Expected element to be within the layout');
expect(item.style.opacity).toBeFalsy('Expected element to be visible');
expect(preview.parentNode).toBeFalsy('Expected preview to be removed from the DOM');
}));

Expand Down
6 changes: 3 additions & 3 deletions src/cdk/drag-drop/drag-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {coerceBooleanProperty, coerceElement} from '@angular/cdk/coercion';
import {Subscription, Subject, Observable} from 'rxjs';
import {DropListRefInternal as DropListRef} from './drop-list-ref';
import {DragDropRegistry} from './drag-drop-registry';
import {extendStyles, toggleNativeDragInteractions} from './drag-styling';
import {extendStyles, toggleNativeDragInteractions, toggleVisibility} from './drag-styling';
import {getTransformTransitionDurationInMs} from './transition-duration';
import {getMutableClientRect, adjustClientRect} from './client-rect';
import {ParentPositionTracker} from './parent-position-tracker';
Expand Down Expand Up @@ -730,7 +730,7 @@ export class DragRef<T = any> {
// We move the element out at the end of the body and we make it hidden, because keeping it in
// place will throw off the consumer's `:last-child` selectors. We can't remove the element
// from the DOM completely, because iOS will stop firing all subsequent events in the chain.
element.style.display = 'none';
toggleVisibility(element, false);
this._document.body.appendChild(parent.replaceChild(placeholder, element));
getPreviewInsertionPoint(this._document).appendChild(preview);
this.started.next({source: this}); // Emit before notifying the container.
Expand Down Expand Up @@ -825,7 +825,7 @@ export class DragRef<T = any> {
// It's important that we maintain the position, because moving the element around in the DOM
// can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,
// while moving the existing elements in all other cases.
this._rootElement.style.display = '';
toggleVisibility(this._rootElement, true);
this._anchor.parentNode!.replaceChild(this._rootElement, this._anchor);

this._destroyPreview();
Expand Down
13 changes: 13 additions & 0 deletions src/cdk/drag-drop/drag-styling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,16 @@ export function toggleNativeDragInteractions(element: HTMLElement, enable: boole
MozUserSelect: userSelect
});
}

/**
* Toggles whether an element is visible while preserving its dimensions.
* @param element Element whose visibility to toggle
* @param enable Whether the element should be visible.
* @docs-private
*/
export function toggleVisibility(element: HTMLElement, enable: boolean) {
const styles = element.style;
styles.position = enable ? '' : 'fixed';
styles.top = styles.opacity = enable ? '' : '0';
styles.left = enable ? '' : '-999em';
}