Skip to content

Commit 56f679b

Browse files
committed
fix(drag-drop): preview not being rendered inside fullscreen element
Fixes the drag preview not being rendered when the user goes into fullscreen mode. Fixes #15033.
1 parent 5846038 commit 56f679b

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/cdk/drag-drop/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ng_test_library(
2323
name = "drag-drop_test_sources",
2424
srcs = glob(["**/*.spec.ts"]),
2525
deps = [
26+
"@angular//packages/common",
2627
"@rxjs",
2728
"//src/cdk/testing",
2829
"//src/cdk/bidi",

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ChangeDetectionStrategy,
1313
} from '@angular/core';
1414
import {TestBed, ComponentFixture, fakeAsync, flush, tick} from '@angular/core/testing';
15+
import {DOCUMENT} from '@angular/common';
1516
import {DragDropModule} from '../drag-drop-module';
1617
import {
1718
createMouseEvent,
@@ -1248,6 +1249,41 @@ describe('CdkDrag', () => {
12481249
expect(preview.parentNode).toBeFalsy('Expected preview to be removed from the DOM');
12491250
}));
12501251

1252+
it('should create the preview inside the fullscreen element when in fullscreen mode',
1253+
fakeAsync(() => {
1254+
// Provide a limited stub of the document since we can't trigger fullscreen
1255+
// mode in unit tests and there are some issues with doing it in e2e tests.
1256+
const fakeDocument = {
1257+
body: document.body,
1258+
fullscreenElement: document.createElement('div'),
1259+
ELEMENT_NODE: Node.ELEMENT_NODE,
1260+
querySelectorAll: function() {
1261+
return document.querySelectorAll.apply(document, arguments);
1262+
},
1263+
addEventListener: function() {
1264+
document.addEventListener.apply(document, arguments);
1265+
},
1266+
removeEventListener: function() {
1267+
document.addEventListener.apply(document, arguments);
1268+
}
1269+
};
1270+
const fixture = createComponent(DraggableInDropZone, [{
1271+
provide: DOCUMENT,
1272+
useFactory: () => fakeDocument
1273+
}]);
1274+
fixture.detectChanges();
1275+
const item = fixture.componentInstance.dragItems.toArray()[1].element.nativeElement;
1276+
1277+
document.body.appendChild(fakeDocument.fullscreenElement);
1278+
startDraggingViaMouse(fixture, item);
1279+
flush();
1280+
1281+
const preview = document.querySelector('.cdk-drag-preview')! as HTMLElement;
1282+
1283+
expect(preview.parentNode).toBe(fakeDocument.fullscreenElement);
1284+
fakeDocument.fullscreenElement.parentNode!.removeChild(fakeDocument.fullscreenElement);
1285+
}));
1286+
12511287
it('should be able to constrain the preview position', fakeAsync(() => {
12521288
const fixture = createComponent(DraggableInDropZone);
12531289
fixture.componentInstance.boundarySelector = '.cdk-drop-list';

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ export class DragRef<T = any> {
603603
// from the DOM completely, because iOS will stop firing all subsequent events in the chain.
604604
element.style.display = 'none';
605605
this._document.body.appendChild(element.parentNode!.replaceChild(placeholder, element));
606-
this._document.body.appendChild(preview);
606+
getPreviewInsertionPoint(this._document).appendChild(preview);
607607
this._dropContainer.start();
608608
}
609609
}
@@ -1016,3 +1016,15 @@ function removeElement(element: HTMLElement | null) {
10161016
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
10171017
return event.type.startsWith('touch');
10181018
}
1019+
1020+
/** Gets the element into which the drag preview should be inserted. */
1021+
function getPreviewInsertionPoint(documentRef: any): HTMLElement {
1022+
// We can't use the body if the user is in fullscreen mode,
1023+
// because the preview will render under the fullscreen element.
1024+
// TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.
1025+
return documentRef.fullscreenElement ||
1026+
documentRef.webkitFullscreenElement ||
1027+
documentRef.mozFullScreenElement ||
1028+
documentRef.msFullscreenElement ||
1029+
documentRef.body;
1030+
}

0 commit comments

Comments
 (0)