Skip to content

Commit f1e1528

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): preview not being rendered inside fullscreen element (#15066)
Fixes the drag preview not being rendered when the user goes into fullscreen mode. Fixes #15033.
1 parent 1aafdbe commit f1e1528

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,
@@ -1320,6 +1321,41 @@ describe('CdkDrag', () => {
13201321
expect(preview.parentNode).toBeFalsy('Expected preview to be removed from the DOM');
13211322
}));
13221323

1324+
it('should create the preview inside the fullscreen element when in fullscreen mode',
1325+
fakeAsync(() => {
1326+
// Provide a limited stub of the document since we can't trigger fullscreen
1327+
// mode in unit tests and there are some issues with doing it in e2e tests.
1328+
const fakeDocument = {
1329+
body: document.body,
1330+
fullscreenElement: document.createElement('div'),
1331+
ELEMENT_NODE: Node.ELEMENT_NODE,
1332+
querySelectorAll: function() {
1333+
return document.querySelectorAll.apply(document, arguments);
1334+
},
1335+
addEventListener: function() {
1336+
document.addEventListener.apply(document, arguments);
1337+
},
1338+
removeEventListener: function() {
1339+
document.addEventListener.apply(document, arguments);
1340+
}
1341+
};
1342+
const fixture = createComponent(DraggableInDropZone, [{
1343+
provide: DOCUMENT,
1344+
useFactory: () => fakeDocument
1345+
}]);
1346+
fixture.detectChanges();
1347+
const item = fixture.componentInstance.dragItems.toArray()[1].element.nativeElement;
1348+
1349+
document.body.appendChild(fakeDocument.fullscreenElement);
1350+
startDraggingViaMouse(fixture, item);
1351+
flush();
1352+
1353+
const preview = document.querySelector('.cdk-drag-preview')! as HTMLElement;
1354+
1355+
expect(preview.parentNode).toBe(fakeDocument.fullscreenElement);
1356+
fakeDocument.fullscreenElement.parentNode!.removeChild(fakeDocument.fullscreenElement);
1357+
}));
1358+
13231359
it('should be able to constrain the preview position', fakeAsync(() => {
13241360
const fixture = createComponent(DraggableInDropZone);
13251361
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
@@ -613,7 +613,7 @@ export class DragRef<T = any> {
613613
// from the DOM completely, because iOS will stop firing all subsequent events in the chain.
614614
element.style.display = 'none';
615615
this._document.body.appendChild(element.parentNode!.replaceChild(placeholder, element));
616-
this._document.body.appendChild(preview);
616+
getPreviewInsertionPoint(this._document).appendChild(preview);
617617
this._dropContainer.start();
618618
}
619619
}
@@ -1027,3 +1027,15 @@ function removeElement(element: HTMLElement | null) {
10271027
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
10281028
return event.type.startsWith('touch');
10291029
}
1030+
1031+
/** Gets the element into which the drag preview should be inserted. */
1032+
function getPreviewInsertionPoint(documentRef: any): HTMLElement {
1033+
// We can't use the body if the user is in fullscreen mode,
1034+
// because the preview will render under the fullscreen element.
1035+
// TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.
1036+
return documentRef.fullscreenElement ||
1037+
documentRef.webkitFullscreenElement ||
1038+
documentRef.mozFullScreenElement ||
1039+
documentRef.msFullscreenElement ||
1040+
documentRef.body;
1041+
}

0 commit comments

Comments
 (0)